]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/home/homed-manager.c
user-util: add get{pw,gr}{uid,gid,name}_malloc() helpers
[thirdparty/systemd.git] / src / home / homed-manager.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <grp.h>
4 #include <linux/fs.h>
5 #include <linux/magic.h>
6 #include <math.h>
7 #include <openssl/pem.h>
8 #include <pwd.h>
9 #include <sys/ioctl.h>
10 #include <sys/quota.h>
11 #include <sys/stat.h>
12
13 #include "sd-id128.h"
14
15 #include "btrfs-util.h"
16 #include "bus-common-errors.h"
17 #include "bus-error.h"
18 #include "bus-log-control-api.h"
19 #include "bus-polkit.h"
20 #include "clean-ipc.h"
21 #include "common-signal.h"
22 #include "conf-files.h"
23 #include "device-util.h"
24 #include "dirent-util.h"
25 #include "fd-util.h"
26 #include "fileio.h"
27 #include "format-util.h"
28 #include "fs-util.h"
29 #include "glyph-util.h"
30 #include "gpt.h"
31 #include "home-util.h"
32 #include "homed-conf.h"
33 #include "homed-home-bus.h"
34 #include "homed-home.h"
35 #include "homed-manager-bus.h"
36 #include "homed-manager.h"
37 #include "homed-varlink.h"
38 #include "io-util.h"
39 #include "mkdir.h"
40 #include "openssl-util.h"
41 #include "process-util.h"
42 #include "quota-util.h"
43 #include "random-util.h"
44 #include "resize-fs.h"
45 #include "socket-util.h"
46 #include "sort-util.h"
47 #include "stat-util.h"
48 #include "strv.h"
49 #include "sync-util.h"
50 #include "tmpfile-util.h"
51 #include "udev-util.h"
52 #include "user-record-sign.h"
53 #include "user-record-util.h"
54 #include "user-record.h"
55 #include "user-util.h"
56 #include "varlink-io.systemd.UserDatabase.h"
57
58 /* Where to look for private/public keys that are used to sign the user records. We are not using
59 * CONF_PATHS_NULSTR() here since we want to insert /var/lib/systemd/home/ in the middle. And we insert that
60 * since we want to auto-generate a persistent private/public key pair if we need to. */
61 #define KEY_PATHS_NULSTR \
62 "/etc/systemd/home/\0" \
63 "/run/systemd/home/\0" \
64 "/var/lib/systemd/home/\0" \
65 "/usr/local/lib/systemd/home/\0" \
66 "/usr/lib/systemd/home/\0"
67
68 static bool uid_is_home(uid_t uid) {
69 return uid >= HOME_UID_MIN && uid <= HOME_UID_MAX;
70 }
71 /* Takes a value generated randomly or by hashing and turns it into a UID in the right range */
72
73 #define UID_CLAMP_INTO_HOME_RANGE(rnd) (((uid_t) (rnd) % (HOME_UID_MAX - HOME_UID_MIN + 1)) + HOME_UID_MIN)
74
75 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_uid_hash_ops, void, trivial_hash_func, trivial_compare_func, Home, home_free);
76 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_name_hash_ops, char, string_hash_func, string_compare_func, Home, home_free);
77 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_worker_pid_hash_ops, void, trivial_hash_func, trivial_compare_func, Home, home_free);
78 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_sysfs_hash_ops, char, path_hash_func, path_compare, Home, home_free);
79
80 static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata);
81 static int manager_gc_images(Manager *m);
82 static int manager_enumerate_images(Manager *m);
83 static int manager_assess_image(Manager *m, int dir_fd, const char *dir_path, const char *dentry_name);
84 static void manager_revalidate_image(Manager *m, Home *h);
85
86 static void manager_watch_home(Manager *m) {
87 struct statfs sfs;
88 int r;
89
90 assert(m);
91
92 m->inotify_event_source = sd_event_source_disable_unref(m->inotify_event_source);
93 m->scan_slash_home = false;
94
95 if (statfs(get_home_root(), &sfs) < 0) {
96 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
97 "Failed to statfs() %s directory, disabling automatic scanning.", get_home_root());
98 return;
99 }
100
101 if (is_network_fs(&sfs)) {
102 log_info("%s is a network file system, disabling automatic scanning.", get_home_root());
103 return;
104 }
105
106 if (is_fs_type(&sfs, AUTOFS_SUPER_MAGIC)) {
107 log_info("%s is on autofs, disabling automatic scanning.", get_home_root());
108 return;
109 }
110
111 m->scan_slash_home = true;
112
113 r = sd_event_add_inotify(m->event, &m->inotify_event_source, get_home_root(),
114 IN_CREATE|IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF|IN_ONLYDIR|IN_MOVED_TO|IN_MOVED_FROM|IN_DELETE,
115 on_home_inotify, m);
116 if (r < 0)
117 log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
118 "Failed to create inotify watch on %s, ignoring.", get_home_root());
119
120 (void) sd_event_source_set_description(m->inotify_event_source, "home-inotify");
121
122 log_info("Watching %s.", get_home_root());
123 }
124
125 static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata) {
126 _cleanup_free_ char *j = NULL;
127 Manager *m = ASSERT_PTR(userdata);
128 const char *e, *n;
129
130 assert(event);
131
132 if ((event->mask & (IN_Q_OVERFLOW|IN_MOVE_SELF|IN_DELETE_SELF|IN_IGNORED|IN_UNMOUNT)) != 0) {
133
134 if (FLAGS_SET(event->mask, IN_Q_OVERFLOW))
135 log_debug("%s inotify queue overflow, rescanning.", get_home_root());
136 else if (FLAGS_SET(event->mask, IN_MOVE_SELF))
137 log_info("%s moved or renamed, recreating watch and rescanning.", get_home_root());
138 else if (FLAGS_SET(event->mask, IN_DELETE_SELF))
139 log_info("%s deleted, recreating watch and rescanning.", get_home_root());
140 else if (FLAGS_SET(event->mask, IN_UNMOUNT))
141 log_info("%s unmounted, recreating watch and rescanning.", get_home_root());
142 else if (FLAGS_SET(event->mask, IN_IGNORED))
143 log_info("%s watch invalidated, recreating watch and rescanning.", get_home_root());
144
145 manager_watch_home(m);
146 (void) manager_gc_images(m);
147 (void) manager_enumerate_images(m);
148 (void) bus_manager_emit_auto_login_changed(m);
149 return 0;
150 }
151
152 /* For the other inotify events, let's ignore all events for file names that don't match our
153 * expectations */
154 if (isempty(event->name))
155 return 0;
156 e = endswith(event->name, FLAGS_SET(event->mask, IN_ISDIR) ? ".homedir" : ".home");
157 if (!e)
158 return 0;
159
160 n = strndupa_safe(event->name, e - event->name);
161 if (!suitable_user_name(n))
162 return 0;
163
164 j = path_join(get_home_root(), event->name);
165 if (!j)
166 return log_oom();
167
168 if ((event->mask & (IN_CREATE|IN_CLOSE_WRITE|IN_MOVED_TO)) != 0) {
169 if (FLAGS_SET(event->mask, IN_CREATE))
170 log_debug("%s has been created, having a look.", j);
171 else if (FLAGS_SET(event->mask, IN_CLOSE_WRITE))
172 log_debug("%s has been modified, having a look.", j);
173 else if (FLAGS_SET(event->mask, IN_MOVED_TO))
174 log_debug("%s has been moved in, having a look.", j);
175
176 (void) manager_assess_image(m, -1, get_home_root(), event->name);
177 (void) bus_manager_emit_auto_login_changed(m);
178 }
179
180 if ((event->mask & (IN_DELETE | IN_CLOSE_WRITE | IN_MOVED_FROM)) != 0) {
181 Home *h;
182
183 if (FLAGS_SET(event->mask, IN_DELETE))
184 log_debug("%s has been deleted, revalidating.", j);
185 else if (FLAGS_SET(event->mask, IN_CLOSE_WRITE))
186 log_debug("%s has been closed after writing, revalidating.", j);
187 else if (FLAGS_SET(event->mask, IN_MOVED_FROM))
188 log_debug("%s has been moved away, revalidating.", j);
189
190 h = hashmap_get(m->homes_by_name, n);
191 if (h) {
192 manager_revalidate_image(m, h);
193 (void) bus_manager_emit_auto_login_changed(m);
194 }
195 }
196
197 return 0;
198 }
199
200 int manager_new(Manager **ret) {
201 _cleanup_(manager_freep) Manager *m = NULL;
202 int r;
203
204 assert(ret);
205
206 m = new(Manager, 1);
207 if (!m)
208 return -ENOMEM;
209
210 *m = (Manager) {
211 .default_storage = _USER_STORAGE_INVALID,
212 .rebalance_interval_usec = 2 * USEC_PER_MINUTE, /* initially, rebalance every 2min */
213 };
214
215 r = manager_parse_config_file(m);
216 if (r < 0)
217 return r;
218
219 r = sd_event_default(&m->event);
220 if (r < 0)
221 return r;
222
223 r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
224 if (r < 0)
225 return r;
226
227 r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
228 if (r < 0)
229 return r;
230
231 r = sd_event_add_memory_pressure(m->event, NULL, NULL, NULL);
232 if (r < 0)
233 log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || (r == -EHOSTDOWN) ? LOG_DEBUG : LOG_WARNING, r,
234 "Failed to allocate memory pressure watch, ignoring: %m");
235
236 r = sd_event_add_signal(m->event, NULL, SIGRTMIN+18, sigrtmin18_handler, NULL);
237 if (r < 0)
238 return r;
239
240 (void) sd_event_set_watchdog(m->event, true);
241
242 m->homes_by_uid = hashmap_new(&homes_by_uid_hash_ops);
243 if (!m->homes_by_uid)
244 return -ENOMEM;
245
246 m->homes_by_name = hashmap_new(&homes_by_name_hash_ops);
247 if (!m->homes_by_name)
248 return -ENOMEM;
249
250 m->homes_by_worker_pid = hashmap_new(&homes_by_worker_pid_hash_ops);
251 if (!m->homes_by_worker_pid)
252 return -ENOMEM;
253
254 m->homes_by_sysfs = hashmap_new(&homes_by_sysfs_hash_ops);
255 if (!m->homes_by_sysfs)
256 return -ENOMEM;
257
258 *ret = TAKE_PTR(m);
259 return 0;
260 }
261
262 Manager* manager_free(Manager *m) {
263 Home *h;
264
265 assert(m);
266
267 HASHMAP_FOREACH(h, m->homes_by_worker_pid)
268 (void) home_wait_for_worker(h);
269
270 m->bus = sd_bus_flush_close_unref(m->bus);
271 m->polkit_registry = hashmap_free(m->polkit_registry);
272
273 m->device_monitor = sd_device_monitor_unref(m->device_monitor);
274
275 m->inotify_event_source = sd_event_source_unref(m->inotify_event_source);
276 m->notify_socket_event_source = sd_event_source_unref(m->notify_socket_event_source);
277 m->deferred_rescan_event_source = sd_event_source_unref(m->deferred_rescan_event_source);
278 m->deferred_gc_event_source = sd_event_source_unref(m->deferred_gc_event_source);
279 m->deferred_auto_login_event_source = sd_event_source_unref(m->deferred_auto_login_event_source);
280 m->rebalance_event_source = sd_event_source_unref(m->rebalance_event_source);
281
282 m->event = sd_event_unref(m->event);
283
284 m->homes_by_uid = hashmap_free(m->homes_by_uid);
285 m->homes_by_name = hashmap_free(m->homes_by_name);
286 m->homes_by_worker_pid = hashmap_free(m->homes_by_worker_pid);
287 m->homes_by_sysfs = hashmap_free(m->homes_by_sysfs);
288
289 if (m->private_key)
290 EVP_PKEY_free(m->private_key);
291
292 hashmap_free(m->public_keys);
293
294 varlink_server_unref(m->varlink_server);
295 free(m->userdb_service);
296
297 free(m->default_file_system_type);
298
299 return mfree(m);
300 }
301
302 int manager_verify_user_record(Manager *m, UserRecord *hr) {
303 EVP_PKEY *pkey;
304 int r;
305
306 assert(m);
307 assert(hr);
308
309 if (!m->private_key && hashmap_isempty(m->public_keys)) {
310 r = user_record_has_signature(hr);
311 if (r < 0)
312 return r;
313
314 return r ? -ENOKEY : USER_RECORD_UNSIGNED;
315 }
316
317 /* Is it our own? */
318 if (m->private_key) {
319 r = user_record_verify(hr, m->private_key);
320 switch (r) {
321
322 case USER_RECORD_FOREIGN:
323 /* This record is not signed by this key, but let's see below */
324 break;
325
326 case USER_RECORD_SIGNED: /* Signed by us, but also by others, let's propagate that */
327 case USER_RECORD_SIGNED_EXCLUSIVE: /* Signed by us, and nothing else, ditto */
328 case USER_RECORD_UNSIGNED: /* Not signed at all, ditto */
329 default:
330 return r;
331 }
332 }
333
334 HASHMAP_FOREACH(pkey, m->public_keys) {
335 r = user_record_verify(hr, pkey);
336 switch (r) {
337
338 case USER_RECORD_FOREIGN:
339 /* This record is not signed by this key, but let's see our other keys */
340 break;
341
342 case USER_RECORD_SIGNED: /* It's signed by this key we are happy with, but which is not our own. */
343 case USER_RECORD_SIGNED_EXCLUSIVE:
344 return USER_RECORD_FOREIGN;
345
346 case USER_RECORD_UNSIGNED: /* It's not signed at all */
347 default:
348 return r;
349 }
350 }
351
352 return -ENOKEY;
353 }
354
355 static int manager_add_home_by_record(
356 Manager *m,
357 const char *name,
358 int dir_fd,
359 const char *fname) {
360
361 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
362 _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
363 unsigned line, column;
364 int r, is_signed;
365 struct stat st;
366 Home *h;
367
368 assert(m);
369 assert(name);
370 assert(fname);
371
372 if (fstatat(dir_fd, fname, &st, 0) < 0)
373 return log_error_errno(errno, "Failed to stat identity record %s: %m", fname);
374
375 if (!S_ISREG(st.st_mode)) {
376 log_debug("Identity record file %s is not a regular file, ignoring.", fname);
377 return 0;
378 }
379
380 if (st.st_size == 0)
381 goto unlink_this_file;
382
383 r = json_parse_file_at(NULL, dir_fd, fname, JSON_PARSE_SENSITIVE, &v, &line, &column);
384 if (r < 0)
385 return log_error_errno(r, "Failed to parse identity record at %s:%u%u: %m", fname, line, column);
386
387 if (json_variant_is_blank_object(v))
388 goto unlink_this_file;
389
390 hr = user_record_new();
391 if (!hr)
392 return log_oom();
393
394 r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
395 if (r < 0)
396 return r;
397
398 if (!streq_ptr(hr->user_name, name))
399 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
400 "Identity's user name %s does not match file name %s, refusing.",
401 hr->user_name, name);
402
403 is_signed = manager_verify_user_record(m, hr);
404 switch (is_signed) {
405
406 case -ENOKEY:
407 return log_warning_errno(is_signed, "User record %s is not signed by any accepted key, ignoring.", fname);
408 case USER_RECORD_UNSIGNED:
409 return log_warning_errno(SYNTHETIC_ERRNO(EPERM), "User record %s is not signed at all, ignoring.", fname);
410 case USER_RECORD_SIGNED:
411 log_info("User record %s is signed by us (and others), accepting.", fname);
412 break;
413 case USER_RECORD_SIGNED_EXCLUSIVE:
414 log_info("User record %s is signed only by us, accepting.", fname);
415 break;
416 case USER_RECORD_FOREIGN:
417 log_info("User record %s is signed by registered key from others, accepting.", fname);
418 break;
419 default:
420 assert(is_signed < 0);
421 return log_error_errno(is_signed, "Failed to verify signature of user record in %s: %m", fname);
422 }
423
424 h = hashmap_get(m->homes_by_name, name);
425 if (h) {
426 r = home_set_record(h, hr);
427 if (r < 0)
428 return log_error_errno(r, "Failed to update home record for %s: %m", name);
429
430 /* If we acquired a record now for a previously unallocated entry, then reset the state. This
431 * makes sure home_get_state() will check for the availability of the image file dynamically
432 * in order to detect to distinguish HOME_INACTIVE and HOME_ABSENT. */
433 if (h->state == HOME_UNFIXATED)
434 h->state = _HOME_STATE_INVALID;
435 } else {
436 r = home_new(m, hr, NULL, &h);
437 if (r < 0)
438 return log_error_errno(r, "Failed to allocate new home object: %m");
439
440 log_info("Added registered home for user %s.", hr->user_name);
441 }
442
443 /* Only entries we exclusively signed are writable to us, hence remember the result */
444 h->signed_locally = is_signed == USER_RECORD_SIGNED_EXCLUSIVE;
445
446 return 1;
447
448 unlink_this_file:
449 /* If this is an empty file, then let's just remove it. An empty file is not useful in any case, and
450 * apparently xfs likes to leave empty files around when not unmounted cleanly (see
451 * https://github.com/systemd/systemd/issues/15178 for example). Note that we don't delete non-empty
452 * files even if they are invalid, because that's just too risky, we might delete data the user still
453 * needs. But empty files are never useful, hence let's just remove them. */
454
455 if (unlinkat(dir_fd, fname, 0) < 0)
456 return log_error_errno(errno, "Failed to remove empty user record file %s: %m", fname);
457
458 log_notice("Discovered empty user record file %s/%s, removed automatically.", home_record_dir(), fname);
459 return 0;
460 }
461
462 static int manager_enumerate_records(Manager *m) {
463 _cleanup_closedir_ DIR *d = NULL;
464
465 assert(m);
466
467 d = opendir(home_record_dir());
468 if (!d)
469 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
470 "Failed to open %s: %m", home_record_dir());
471
472 FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read record directory: %m")) {
473 _cleanup_free_ char *n = NULL;
474 const char *e;
475
476 if (!dirent_is_file(de))
477 continue;
478
479 e = endswith(de->d_name, ".identity");
480 if (!e)
481 continue;
482
483 n = strndup(de->d_name, e - de->d_name);
484 if (!n)
485 return log_oom();
486
487 if (!suitable_user_name(n))
488 continue;
489
490 (void) manager_add_home_by_record(m, n, dirfd(d), de->d_name);
491 }
492
493 return 0;
494 }
495
496 static int search_quota(uid_t uid, const char *exclude_quota_path) {
497 struct stat exclude_st = {};
498 dev_t previous_devno = 0;
499 int r;
500
501 /* Checks whether the specified UID owns any files on the files system, but ignore any file system
502 * backing the specified file. The file is used when operating on home directories, where it's OK if
503 * the UID of them already owns files. */
504
505 if (exclude_quota_path && stat(exclude_quota_path, &exclude_st) < 0) {
506 if (errno != ENOENT)
507 return log_warning_errno(errno, "Failed to stat %s, ignoring: %m", exclude_quota_path);
508 }
509
510 /* Check a few usual suspects where regular users might own files. Note that this is by no means
511 * comprehensive, but should cover most cases. Note that in an ideal world every user would be
512 * registered in NSS and avoid our own UID range, but for all other cases, it's a good idea to be
513 * paranoid and check quota if we can. */
514 FOREACH_STRING(where, get_home_root(), "/tmp/", "/var/", "/var/mail/", "/var/tmp/", "/var/spool/") {
515 struct dqblk req;
516 struct stat st;
517
518 if (stat(where, &st) < 0) {
519 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
520 "Failed to stat %s, ignoring: %m", where);
521 continue;
522 }
523
524 if (major(st.st_dev) == 0) {
525 log_debug("Directory %s is not on a real block device, not checking quota for UID use.", where);
526 continue;
527 }
528
529 if (st.st_dev == exclude_st.st_dev) { /* If an exclude path is specified, then ignore quota
530 * reported on the same block device as that path. */
531 log_debug("Directory %s is where the home directory is located, not checking quota for UID use.", where);
532 continue;
533 }
534
535 if (st.st_dev == previous_devno) { /* Does this directory have the same devno as the previous
536 * one we tested? If so, there's no point in testing this
537 * again. */
538 log_debug("Directory %s is on same device as previous tested directory, not checking quota for UID use a second time.", where);
539 continue;
540 }
541
542 previous_devno = st.st_dev;
543
544 r = quotactl_devnum(QCMD_FIXED(Q_GETQUOTA, USRQUOTA), st.st_dev, uid, &req);
545 if (r < 0) {
546 if (ERRNO_IS_NOT_SUPPORTED(r))
547 log_debug_errno(r, "No UID quota support on %s, ignoring.", where);
548 else if (ERRNO_IS_PRIVILEGE(r))
549 log_debug_errno(r, "UID quota support for %s prohibited, ignoring.", where);
550 else
551 log_warning_errno(r, "Failed to query quota on %s, ignoring: %m", where);
552
553 continue;
554 }
555
556 if ((FLAGS_SET(req.dqb_valid, QIF_SPACE) && req.dqb_curspace > 0) ||
557 (FLAGS_SET(req.dqb_valid, QIF_INODES) && req.dqb_curinodes > 0)) {
558 log_debug_errno(errno, "Quota reports UID " UID_FMT " occupies disk space on %s.", uid, where);
559 return 1;
560 }
561 }
562
563 return 0;
564 }
565
566 static int manager_acquire_uid(
567 Manager *m,
568 uid_t start_uid,
569 const char *user_name,
570 const char *exclude_quota_path,
571 uid_t *ret) {
572
573 static const uint8_t hash_key[] = {
574 0xa3, 0xb8, 0x82, 0x69, 0x9a, 0x71, 0xf7, 0xa9,
575 0xe0, 0x7c, 0xf6, 0xf1, 0x21, 0x69, 0xd2, 0x1e
576 };
577
578 enum {
579 PHASE_SUGGESTED,
580 PHASE_HASHED,
581 PHASE_RANDOM
582 } phase = PHASE_SUGGESTED;
583
584 unsigned n_tries = 100;
585 int r;
586
587 assert(m);
588 assert(ret);
589
590 for (;;) {
591 _cleanup_free_ struct passwd *pw = NULL;
592 _cleanup_free_ struct group *gr = NULL;
593 uid_t candidate;
594 Home *other;
595
596 if (--n_tries <= 0)
597 return -EBUSY;
598
599 switch (phase) {
600
601 case PHASE_SUGGESTED:
602 phase = PHASE_HASHED;
603
604 if (!uid_is_home(start_uid))
605 continue;
606
607 candidate = start_uid;
608 break;
609
610 case PHASE_HASHED:
611 phase = PHASE_RANDOM;
612
613 if (!user_name)
614 continue;
615
616 candidate = UID_CLAMP_INTO_HOME_RANGE(siphash24(user_name, strlen(user_name), hash_key));
617 break;
618
619 case PHASE_RANDOM:
620 random_bytes(&candidate, sizeof(candidate));
621 candidate = UID_CLAMP_INTO_HOME_RANGE(candidate);
622 break;
623
624 default:
625 assert_not_reached();
626 }
627
628 other = hashmap_get(m->homes_by_uid, UID_TO_PTR(candidate));
629 if (other) {
630 log_debug("Candidate UID " UID_FMT " already used by another home directory (%s), let's try another.",
631 candidate, other->user_name);
632 continue;
633 }
634
635 r = getpwuid_malloc(candidate, &pw);
636 if (r >= 0) {
637 log_debug("Candidate UID " UID_FMT " already registered by another user in NSS (%s), let's try another.",
638 candidate, pw->pw_name);
639 continue;
640 }
641 if (r != -ESRCH) {
642 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);
643 continue;
644 }
645
646 r = getgrgid_malloc((gid_t) candidate, &gr);
647 if (r >= 0) {
648 log_debug("Candidate UID " UID_FMT " already registered by another group in NSS (%s), let's try another.",
649 candidate, gr->gr_name);
650 continue;
651 }
652 if (r != -ESRCH) {
653 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);
654 continue;
655 }
656
657 r = search_ipc(candidate, (gid_t) candidate);
658 if (r < 0)
659 continue;
660 if (r > 0) {
661 log_debug_errno(r, "Candidate UID " UID_FMT " already owns IPC objects, let's try another: %m",
662 candidate);
663 continue;
664 }
665
666 r = search_quota(candidate, exclude_quota_path);
667 if (r != 0)
668 continue;
669
670 *ret = candidate;
671 return 0;
672 }
673 }
674
675 static int manager_add_home_by_image(
676 Manager *m,
677 const char *user_name,
678 const char *realm,
679 const char *image_path,
680 const char *sysfs,
681 UserStorage storage,
682 uid_t start_uid) {
683
684 _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
685 uid_t uid;
686 Home *h;
687 int r;
688
689 assert(m);
690
691 assert(m);
692 assert(user_name);
693 assert(image_path);
694 assert(storage >= 0);
695 assert(storage < _USER_STORAGE_MAX);
696
697 h = hashmap_get(m->homes_by_name, user_name);
698 if (h) {
699 bool same;
700
701 if (h->state != HOME_UNFIXATED) {
702 log_debug("Found an image for user %s which already has a record, skipping.", user_name);
703 return 0; /* ignore images that synthesize a user we already have a record for */
704 }
705
706 same = user_record_storage(h->record) == storage;
707 if (same) {
708 if (h->sysfs && sysfs)
709 same = path_equal(h->sysfs, sysfs);
710 else if (!!h->sysfs != !!sysfs)
711 same = false;
712 else {
713 const char *p;
714
715 p = user_record_image_path(h->record);
716 same = p && path_equal(p, image_path);
717 }
718 }
719
720 if (!same) {
721 log_debug("Found multiple images for user '%s', ignoring image '%s'.", user_name, image_path);
722 return 0;
723 }
724 } else {
725 /* Check NSS, in case there's another user or group by this name */
726 if (getpwnam_malloc(user_name, /* ret= */ NULL) >= 0 || getgrnam_malloc(user_name, /* ret= */ NULL) >= 0) {
727 log_debug("Found an existing user or group by name '%s', ignoring image '%s'.", user_name, image_path);
728 return 0;
729 }
730 }
731
732 if (h && uid_is_valid(h->uid))
733 uid = h->uid;
734 else {
735 r = manager_acquire_uid(m, start_uid, user_name,
736 IN_SET(storage, USER_SUBVOLUME, USER_DIRECTORY, USER_FSCRYPT) ? image_path : NULL,
737 &uid);
738 if (r < 0)
739 return log_warning_errno(r, "Failed to acquire unused UID for %s: %m", user_name);
740 }
741
742 hr = user_record_new();
743 if (!hr)
744 return log_oom();
745
746 r = user_record_synthesize(hr, user_name, realm, image_path, storage, uid, (gid_t) uid);
747 if (r < 0)
748 return log_error_errno(r, "Failed to synthesize home record for %s (image %s): %m", user_name, image_path);
749
750 if (h) {
751 r = home_set_record(h, hr);
752 if (r < 0)
753 return log_error_errno(r, "Failed to update home record for %s: %m", user_name);
754 } else {
755 r = home_new(m, hr, sysfs, &h);
756 if (r < 0)
757 return log_error_errno(r, "Failed to allocate new home object: %m");
758
759 h->state = HOME_UNFIXATED;
760
761 log_info("Discovered new home for user %s through image %s.", user_name, image_path);
762 }
763
764 return 1;
765 }
766
767 int manager_augment_record_with_uid(
768 Manager *m,
769 UserRecord *hr) {
770
771 const char *exclude_quota_path = NULL;
772 uid_t start_uid = UID_INVALID, uid;
773 int r;
774
775 assert(m);
776 assert(hr);
777
778 if (uid_is_valid(hr->uid))
779 return 0;
780
781 if (IN_SET(hr->storage, USER_CLASSIC, USER_SUBVOLUME, USER_DIRECTORY, USER_FSCRYPT)) {
782 const char * ip;
783
784 ip = user_record_image_path(hr);
785 if (ip) {
786 struct stat st;
787
788 if (stat(ip, &st) < 0) {
789 if (errno != ENOENT)
790 log_warning_errno(errno, "Failed to stat(%s): %m", ip);
791 } else if (uid_is_home(st.st_uid)) {
792 start_uid = st.st_uid;
793 exclude_quota_path = ip;
794 }
795 }
796 }
797
798 r = manager_acquire_uid(m, start_uid, hr->user_name, exclude_quota_path, &uid);
799 if (r < 0)
800 return r;
801
802 log_debug("Acquired new UID " UID_FMT " for %s.", uid, hr->user_name);
803
804 r = user_record_add_binding(
805 hr,
806 _USER_STORAGE_INVALID,
807 NULL,
808 SD_ID128_NULL,
809 SD_ID128_NULL,
810 SD_ID128_NULL,
811 NULL,
812 NULL,
813 UINT64_MAX,
814 NULL,
815 NULL,
816 uid,
817 (gid_t) uid);
818 if (r < 0)
819 return r;
820
821 return 1;
822 }
823
824 static int manager_assess_image(
825 Manager *m,
826 int dir_fd,
827 const char *dir_path,
828 const char *dentry_name) {
829
830 char *luks_suffix, *directory_suffix;
831 _cleanup_free_ char *path = NULL;
832 struct stat st;
833 int r;
834
835 assert(m);
836 assert(dir_path);
837 assert(dentry_name);
838
839 luks_suffix = endswith(dentry_name, ".home");
840 if (luks_suffix)
841 directory_suffix = NULL;
842 else
843 directory_suffix = endswith(dentry_name, ".homedir");
844
845 /* Early filter out: by name */
846 if (!luks_suffix && !directory_suffix)
847 return 0;
848
849 path = path_join(dir_path, dentry_name);
850 if (!path)
851 return log_oom();
852
853 /* Follow symlinks here, to allow people to link in stuff to make them available locally. */
854 if (dir_fd >= 0)
855 r = fstatat(dir_fd, dentry_name, &st, 0);
856 else
857 r = stat(path, &st);
858 if (r < 0)
859 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
860 "Failed to stat() directory entry '%s', ignoring: %m", dentry_name);
861
862 if (S_ISREG(st.st_mode)) {
863 _cleanup_free_ char *n = NULL, *user_name = NULL, *realm = NULL;
864
865 if (!luks_suffix)
866 return 0;
867
868 n = strndup(dentry_name, luks_suffix - dentry_name);
869 if (!n)
870 return log_oom();
871
872 r = split_user_name_realm(n, &user_name, &realm);
873 if (r == -EINVAL) /* Not the right format: ignore */
874 return 0;
875 if (r < 0)
876 return log_error_errno(r, "Failed to split image name into user name/realm: %m");
877
878 return manager_add_home_by_image(m, user_name, realm, path, NULL, USER_LUKS, UID_INVALID);
879 }
880
881 if (S_ISDIR(st.st_mode)) {
882 _cleanup_free_ char *n = NULL, *user_name = NULL, *realm = NULL;
883 _cleanup_close_ int fd = -EBADF;
884 UserStorage storage;
885
886 if (!directory_suffix)
887 return 0;
888
889 n = strndup(dentry_name, directory_suffix - dentry_name);
890 if (!n)
891 return log_oom();
892
893 r = split_user_name_realm(n, &user_name, &realm);
894 if (r == -EINVAL) /* Not the right format: ignore */
895 return 0;
896 if (r < 0)
897 return log_error_errno(r, "Failed to split image name into user name/realm: %m");
898
899 if (dir_fd >= 0)
900 fd = openat(dir_fd, dentry_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
901 else
902 fd = open(path, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
903 if (fd < 0)
904 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
905 "Failed to open directory '%s', ignoring: %m", path);
906
907 if (fstat(fd, &st) < 0)
908 return log_warning_errno(errno, "Failed to fstat() %s, ignoring: %m", path);
909
910 assert(S_ISDIR(st.st_mode)); /* Must hold, we used O_DIRECTORY above */
911
912 r = btrfs_is_subvol_fd(fd);
913 if (r < 0)
914 return log_warning_errno(errno, "Failed to determine whether %s is a btrfs subvolume: %m", path);
915 if (r > 0)
916 storage = USER_SUBVOLUME;
917 else {
918 struct fscrypt_policy policy;
919
920 if (ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) < 0) {
921
922 if (errno == ENODATA)
923 log_debug_errno(errno, "Determined %s is not fscrypt encrypted.", path);
924 else if (ERRNO_IS_NOT_SUPPORTED(errno))
925 log_debug_errno(errno, "Determined %s is not fscrypt encrypted because kernel or file system doesn't support it.", path);
926 else
927 log_debug_errno(errno, "FS_IOC_GET_ENCRYPTION_POLICY failed with unexpected error code on %s, ignoring: %m", path);
928
929 storage = USER_DIRECTORY;
930 } else
931 storage = USER_FSCRYPT;
932 }
933
934 return manager_add_home_by_image(m, user_name, realm, path, NULL, storage, st.st_uid);
935 }
936
937 return 0;
938 }
939
940 int manager_enumerate_images(Manager *m) {
941 _cleanup_closedir_ DIR *d = NULL;
942
943 assert(m);
944
945 if (!m->scan_slash_home)
946 return 0;
947
948 d = opendir(get_home_root());
949 if (!d)
950 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
951 "Failed to open %s: %m", get_home_root());
952
953 FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read %s directory: %m", get_home_root()))
954 (void) manager_assess_image(m, dirfd(d), get_home_root(), de->d_name);
955
956 return 0;
957 }
958
959 static int manager_connect_bus(Manager *m) {
960 _cleanup_free_ char *b = NULL;
961 const char *suffix, *busname;
962 int r;
963
964 assert(m);
965 assert(!m->bus);
966
967 r = sd_bus_default_system(&m->bus);
968 if (r < 0)
969 return log_error_errno(r, "Failed to connect to system bus: %m");
970
971 r = bus_add_implementation(m->bus, &manager_object, m);
972 if (r < 0)
973 return r;
974
975 r = bus_log_control_api_register(m->bus);
976 if (r < 0)
977 return r;
978
979 suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
980 if (suffix) {
981 b = strjoin("org.freedesktop.home1.", suffix);
982 if (!b)
983 return log_oom();
984 busname = b;
985 } else
986 busname = "org.freedesktop.home1";
987
988 r = sd_bus_request_name_async(m->bus, NULL, busname, 0, NULL, NULL);
989 if (r < 0)
990 return log_error_errno(r, "Failed to request name: %m");
991
992 r = sd_bus_attach_event(m->bus, m->event, 0);
993 if (r < 0)
994 return log_error_errno(r, "Failed to attach bus to event loop: %m");
995
996 (void) sd_bus_set_exit_on_disconnect(m->bus, true);
997
998 return 0;
999 }
1000
1001 static int manager_bind_varlink(Manager *m) {
1002 _cleanup_free_ char *p = NULL;
1003 const char *suffix, *socket_path;
1004 int r;
1005
1006 assert(m);
1007 assert(!m->varlink_server);
1008
1009 r = varlink_server_new(&m->varlink_server, VARLINK_SERVER_ACCOUNT_UID|VARLINK_SERVER_INHERIT_USERDATA|VARLINK_SERVER_INPUT_SENSITIVE);
1010 if (r < 0)
1011 return log_error_errno(r, "Failed to allocate varlink server object: %m");
1012
1013 varlink_server_set_userdata(m->varlink_server, m);
1014
1015 r = varlink_server_add_interface(m->varlink_server, &vl_interface_io_systemd_UserDatabase);
1016 if (r < 0)
1017 return log_error_errno(r, "Failed to add UserDatabase interface to varlink server: %m");
1018
1019 r = varlink_server_bind_method_many(
1020 m->varlink_server,
1021 "io.systemd.UserDatabase.GetUserRecord", vl_method_get_user_record,
1022 "io.systemd.UserDatabase.GetGroupRecord", vl_method_get_group_record,
1023 "io.systemd.UserDatabase.GetMemberships", vl_method_get_memberships);
1024 if (r < 0)
1025 return log_error_errno(r, "Failed to register varlink methods: %m");
1026
1027 (void) mkdir_p("/run/systemd/userdb", 0755);
1028
1029 /* To make things easier to debug, when working from a homed managed home directory, let's optionally
1030 * use a different varlink socket name */
1031 suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
1032 if (suffix) {
1033 p = strjoin("/run/systemd/userdb/io.systemd.Home.", suffix);
1034 if (!p)
1035 return log_oom();
1036 socket_path = p;
1037 } else
1038 socket_path = "/run/systemd/userdb/io.systemd.Home";
1039
1040 r = varlink_server_listen_address(m->varlink_server, socket_path, 0666);
1041 if (r < 0)
1042 return log_error_errno(r, "Failed to bind to varlink socket: %m");
1043
1044 r = varlink_server_attach_event(m->varlink_server, m->event, SD_EVENT_PRIORITY_NORMAL);
1045 if (r < 0)
1046 return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
1047
1048 assert(!m->userdb_service);
1049 r = path_extract_filename(socket_path, &m->userdb_service);
1050 if (r < 0)
1051 return log_error_errno(r, "Failed to extra filename from socket path '%s': %m", socket_path);
1052
1053 /* Avoid recursion */
1054 if (setenv("SYSTEMD_BYPASS_USERDB", m->userdb_service, 1) < 0)
1055 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set $SYSTEMD_BYPASS_USERDB: %m");
1056
1057 return 0;
1058 }
1059
1060 static ssize_t read_datagram(
1061 int fd,
1062 struct ucred *ret_sender,
1063 void **ret,
1064 int *ret_passed_fd) {
1065
1066 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int))) control;
1067 _cleanup_free_ void *buffer = NULL;
1068 _cleanup_close_ int passed_fd = -EBADF;
1069 struct ucred *sender = NULL;
1070 struct cmsghdr *cmsg;
1071 struct msghdr mh;
1072 struct iovec iov;
1073 ssize_t n, m;
1074
1075 assert(fd >= 0);
1076 assert(ret_sender);
1077 assert(ret);
1078 assert(ret_passed_fd);
1079
1080 n = next_datagram_size_fd(fd);
1081 if (n < 0)
1082 return n;
1083
1084 buffer = malloc(n + 2);
1085 if (!buffer)
1086 return -ENOMEM;
1087
1088 /* Pass one extra byte, as a size check */
1089 iov = IOVEC_MAKE(buffer, n + 1);
1090
1091 mh = (struct msghdr) {
1092 .msg_iov = &iov,
1093 .msg_iovlen = 1,
1094 .msg_control = &control,
1095 .msg_controllen = sizeof(control),
1096 };
1097
1098 m = recvmsg_safe(fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
1099 if (m < 0)
1100 return m;
1101
1102 /* Ensure the size matches what we determined before */
1103 if (m != n) {
1104 cmsg_close_all(&mh);
1105 return -EMSGSIZE;
1106 }
1107
1108 CMSG_FOREACH(cmsg, &mh) {
1109 if (cmsg->cmsg_level == SOL_SOCKET &&
1110 cmsg->cmsg_type == SCM_CREDENTIALS &&
1111 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1112 assert(!sender);
1113 sender = CMSG_TYPED_DATA(cmsg, struct ucred);
1114 }
1115
1116 if (cmsg->cmsg_level == SOL_SOCKET &&
1117 cmsg->cmsg_type == SCM_RIGHTS) {
1118
1119 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
1120 cmsg_close_all(&mh);
1121 return -EMSGSIZE;
1122 }
1123
1124 assert(passed_fd < 0);
1125 passed_fd = *CMSG_TYPED_DATA(cmsg, int);
1126 }
1127 }
1128
1129 if (sender)
1130 *ret_sender = *sender;
1131 else
1132 *ret_sender = (struct ucred) UCRED_INVALID;
1133
1134 *ret_passed_fd = TAKE_FD(passed_fd);
1135
1136 /* For safety reasons: let's always NUL terminate. */
1137 ((char*) buffer)[n] = 0;
1138 *ret = TAKE_PTR(buffer);
1139
1140 return 0;
1141 }
1142
1143 static int on_notify_socket(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1144 _cleanup_strv_free_ char **l = NULL;
1145 _cleanup_free_ void *datagram = NULL;
1146 _cleanup_close_ int passed_fd = -EBADF;
1147 struct ucred sender = UCRED_INVALID;
1148 Manager *m = ASSERT_PTR(userdata);
1149 ssize_t n;
1150 Home *h;
1151
1152 assert(s);
1153
1154 n = read_datagram(fd, &sender, &datagram, &passed_fd);
1155 if (n < 0) {
1156 if (ERRNO_IS_TRANSIENT(n))
1157 return 0;
1158 return log_error_errno(n, "Failed to read notify datagram: %m");
1159 }
1160
1161 if (sender.pid <= 0) {
1162 log_warning("Received notify datagram without valid sender PID, ignoring.");
1163 return 0;
1164 }
1165
1166 h = hashmap_get(m->homes_by_worker_pid, PID_TO_PTR(sender.pid));
1167 if (!h) {
1168 log_warning("Received notify datagram of unknown process, ignoring.");
1169 return 0;
1170 }
1171
1172 l = strv_split(datagram, "\n");
1173 if (!l)
1174 return log_oom();
1175
1176 home_process_notify(h, l, TAKE_FD(passed_fd));
1177 return 0;
1178 }
1179
1180 static int manager_listen_notify(Manager *m) {
1181 _cleanup_close_ int fd = -EBADF;
1182 union sockaddr_union sa = {
1183 .un.sun_family = AF_UNIX,
1184 .un.sun_path = "/run/systemd/home/notify",
1185 };
1186 const char *suffix;
1187 int r;
1188
1189 assert(m);
1190 assert(!m->notify_socket_event_source);
1191
1192 suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
1193 if (suffix) {
1194 _cleanup_free_ char *unix_path = NULL;
1195
1196 unix_path = strjoin("/run/systemd/home/notify.", suffix);
1197 if (!unix_path)
1198 return log_oom();
1199 r = sockaddr_un_set_path(&sa.un, unix_path);
1200 if (r < 0)
1201 return log_error_errno(r, "Socket path %s does not fit in sockaddr_un: %m", unix_path);
1202 }
1203
1204 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1205 if (fd < 0)
1206 return log_error_errno(errno, "Failed to create listening socket: %m");
1207
1208 (void) mkdir_parents(sa.un.sun_path, 0755);
1209 (void) sockaddr_un_unlink(&sa.un);
1210
1211 if (bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
1212 return log_error_errno(errno, "Failed to bind to socket: %m");
1213
1214 r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true);
1215 if (r < 0)
1216 return r;
1217
1218 r = sd_event_add_io(m->event, &m->notify_socket_event_source, fd, EPOLLIN, on_notify_socket, m);
1219 if (r < 0)
1220 return log_error_errno(r, "Failed to allocate event source for notify socket: %m");
1221
1222 (void) sd_event_source_set_description(m->notify_socket_event_source, "notify-socket");
1223
1224 /* Make sure we process sd_notify() before SIGCHLD for any worker, so that we always know the error
1225 * number of a client before it exits. */
1226 r = sd_event_source_set_priority(m->notify_socket_event_source, SD_EVENT_PRIORITY_NORMAL - 5);
1227 if (r < 0)
1228 return log_error_errno(r, "Failed to alter priority of NOTIFY_SOCKET event source: %m");
1229
1230 r = sd_event_source_set_io_fd_own(m->notify_socket_event_source, true);
1231 if (r < 0)
1232 return log_error_errno(r, "Failed to pass ownership of notify socket: %m");
1233
1234 return TAKE_FD(fd);
1235 }
1236
1237 static int manager_add_device(Manager *m, sd_device *d) {
1238 _cleanup_free_ char *user_name = NULL, *realm = NULL, *node = NULL;
1239 const char *tabletype, *parttype, *partname, *partuuid, *sysfs;
1240 sd_id128_t id;
1241 int r;
1242
1243 assert(m);
1244 assert(d);
1245
1246 r = sd_device_get_syspath(d, &sysfs);
1247 if (r < 0)
1248 return log_error_errno(r, "Failed to acquire sysfs path of device: %m");
1249
1250 r = sd_device_get_property_value(d, "ID_PART_TABLE_TYPE", &tabletype);
1251 if (r == -ENOENT)
1252 return 0;
1253 if (r < 0)
1254 return log_error_errno(r, "Failed to acquire ID_PART_TABLE_TYPE device property, ignoring: %m");
1255
1256 if (!streq(tabletype, "gpt")) {
1257 log_debug("Found partition (%s) on non-GPT table, ignoring.", sysfs);
1258 return 0;
1259 }
1260
1261 r = sd_device_get_property_value(d, "ID_PART_ENTRY_TYPE", &parttype);
1262 if (r == -ENOENT)
1263 return 0;
1264 if (r < 0)
1265 return log_error_errno(r, "Failed to acquire ID_PART_ENTRY_TYPE device property, ignoring: %m");
1266 if (sd_id128_string_equal(parttype, SD_GPT_USER_HOME) <= 0) {
1267 log_debug("Found partition (%s) we don't care about, ignoring.", sysfs);
1268 return 0;
1269 }
1270
1271 r = sd_device_get_property_value(d, "ID_PART_ENTRY_NAME", &partname);
1272 if (r < 0)
1273 return log_warning_errno(r, "Failed to acquire ID_PART_ENTRY_NAME device property, ignoring: %m");
1274
1275 r = split_user_name_realm(partname, &user_name, &realm);
1276 if (r == -EINVAL)
1277 return log_warning_errno(r, "Found partition with correct partition type but a non-parsable partition name '%s', ignoring.", partname);
1278 if (r < 0)
1279 return log_error_errno(r, "Failed to validate partition name '%s': %m", partname);
1280
1281 r = sd_device_get_property_value(d, "ID_FS_UUID", &partuuid);
1282 if (r < 0)
1283 return log_warning_errno(r, "Failed to acquire ID_FS_UUID device property, ignoring: %m");
1284
1285 r = sd_id128_from_string(partuuid, &id);
1286 if (r < 0)
1287 return log_warning_errno(r, "Failed to parse ID_FS_UUID field '%s', ignoring: %m", partuuid);
1288
1289 if (asprintf(&node, "/dev/disk/by-uuid/" SD_ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(id)) < 0)
1290 return log_oom();
1291
1292 return manager_add_home_by_image(m, user_name, realm, node, sysfs, USER_LUKS, UID_INVALID);
1293 }
1294
1295 static int manager_on_device(sd_device_monitor *monitor, sd_device *d, void *userdata) {
1296 Manager *m = ASSERT_PTR(userdata);
1297 int r;
1298
1299 assert(d);
1300
1301 if (device_for_action(d, SD_DEVICE_REMOVE)) {
1302 const char *sysfs;
1303 Home *h;
1304
1305 r = sd_device_get_syspath(d, &sysfs);
1306 if (r < 0) {
1307 log_warning_errno(r, "Failed to acquire sysfs path from device: %m");
1308 return 0;
1309 }
1310
1311 log_info("block device %s has been removed.", sysfs);
1312
1313 /* Let's see if we previously synthesized a home record from this device, if so, let's just
1314 * revalidate that. Otherwise let's revalidate them all, but asynchronously. */
1315 h = hashmap_get(m->homes_by_sysfs, sysfs);
1316 if (h)
1317 manager_revalidate_image(m, h);
1318 else
1319 manager_enqueue_gc(m, NULL);
1320 } else
1321 (void) manager_add_device(m, d);
1322
1323 (void) bus_manager_emit_auto_login_changed(m);
1324 return 0;
1325 }
1326
1327 static int manager_watch_devices(Manager *m) {
1328 int r;
1329
1330 assert(m);
1331 assert(!m->device_monitor);
1332
1333 r = sd_device_monitor_new(&m->device_monitor);
1334 if (r < 0)
1335 return log_error_errno(r, "Failed to allocate device monitor: %m");
1336
1337 r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "block", NULL);
1338 if (r < 0)
1339 return log_error_errno(r, "Failed to configure device monitor match: %m");
1340
1341 r = sd_device_monitor_attach_event(m->device_monitor, m->event);
1342 if (r < 0)
1343 return log_error_errno(r, "Failed to attach device monitor to event loop: %m");
1344
1345 r = sd_device_monitor_start(m->device_monitor, manager_on_device, m);
1346 if (r < 0)
1347 return log_error_errno(r, "Failed to start device monitor: %m");
1348
1349 return 0;
1350 }
1351
1352 static int manager_enumerate_devices(Manager *m) {
1353 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
1354 int r;
1355
1356 assert(m);
1357
1358 r = sd_device_enumerator_new(&e);
1359 if (r < 0)
1360 return r;
1361
1362 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
1363 if (r < 0)
1364 return r;
1365
1366 FOREACH_DEVICE(e, d)
1367 (void) manager_add_device(m, d);
1368
1369 return 0;
1370 }
1371
1372 static int manager_load_key_pair(Manager *m) {
1373 _cleanup_fclose_ FILE *f = NULL;
1374 struct stat st;
1375 int r;
1376
1377 assert(m);
1378
1379 if (m->private_key) {
1380 EVP_PKEY_free(m->private_key);
1381 m->private_key = NULL;
1382 }
1383
1384 r = search_and_fopen_nulstr("local.private", "re", NULL, KEY_PATHS_NULSTR, &f, NULL);
1385 if (r == -ENOENT)
1386 return 0;
1387 if (r < 0)
1388 return log_error_errno(r, "Failed to read private key file: %m");
1389
1390 if (fstat(fileno(f), &st) < 0)
1391 return log_error_errno(errno, "Failed to stat private key file: %m");
1392
1393 r = stat_verify_regular(&st);
1394 if (r < 0)
1395 return log_error_errno(r, "Private key file is not regular: %m");
1396
1397 if (st.st_uid != 0 || (st.st_mode & 0077) != 0)
1398 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Private key file is readable by more than the root user");
1399
1400 m->private_key = PEM_read_PrivateKey(f, NULL, NULL, NULL);
1401 if (!m->private_key)
1402 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to load private key pair");
1403
1404 log_info("Successfully loaded private key pair.");
1405
1406 return 1;
1407 }
1408
1409 static int manager_generate_key_pair(Manager *m) {
1410 _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = NULL;
1411 _cleanup_(unlink_and_freep) char *temp_public = NULL, *temp_private = NULL;
1412 _cleanup_fclose_ FILE *fpublic = NULL, *fprivate = NULL;
1413 int r;
1414
1415 if (m->private_key) {
1416 EVP_PKEY_free(m->private_key);
1417 m->private_key = NULL;
1418 }
1419
1420 ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
1421 if (!ctx)
1422 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to allocate Ed25519 key generation context.");
1423
1424 if (EVP_PKEY_keygen_init(ctx) <= 0)
1425 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize Ed25519 key generation context.");
1426
1427 log_info("Generating key pair for signing local user identity records.");
1428
1429 if (EVP_PKEY_keygen(ctx, &m->private_key) <= 0)
1430 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to generate Ed25519 key pair");
1431
1432 log_info("Successfully created Ed25519 key pair.");
1433
1434 (void) mkdir_p("/var/lib/systemd/home", 0755);
1435
1436 /* Write out public key (note that we only do that as a help to the user, we don't make use of this ever */
1437 r = fopen_temporary("/var/lib/systemd/home/local.public", &fpublic, &temp_public);
1438 if (r < 0)
1439 return log_error_errno(errno, "Failed to open key file for writing: %m");
1440
1441 if (PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
1442 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key.");
1443
1444 r = fflush_sync_and_check(fpublic);
1445 if (r < 0)
1446 return log_error_errno(r, "Failed to write private key: %m");
1447
1448 fpublic = safe_fclose(fpublic);
1449
1450 /* Write out the private key (this actually writes out both private and public, OpenSSL is confusing) */
1451 r = fopen_temporary("/var/lib/systemd/home/local.private", &fprivate, &temp_private);
1452 if (r < 0)
1453 return log_error_errno(errno, "Failed to open key file for writing: %m");
1454
1455 if (PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, 0) <= 0)
1456 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write private key pair.");
1457
1458 r = fflush_sync_and_check(fprivate);
1459 if (r < 0)
1460 return log_error_errno(r, "Failed to write private key: %m");
1461
1462 fprivate = safe_fclose(fprivate);
1463
1464 /* Both are written now, move them into place */
1465
1466 if (rename(temp_public, "/var/lib/systemd/home/local.public") < 0)
1467 return log_error_errno(errno, "Failed to move public key file into place: %m");
1468 temp_public = mfree(temp_public);
1469
1470 r = RET_NERRNO(rename(temp_private, "/var/lib/systemd/home/local.private"));
1471 if (r < 0) {
1472 (void) unlink("/var/lib/systemd/home/local.public"); /* try to remove the file we already created */
1473 return log_error_errno(r, "Failed to move private key file into place: %m");
1474 }
1475 temp_private = mfree(temp_private);
1476
1477 r = fsync_path_at(AT_FDCWD, "/var/lib/systemd/home/");
1478 if (r < 0)
1479 log_warning_errno(r, "Failed to sync /var/lib/systemd/home/, ignoring: %m");
1480
1481 return 1;
1482 }
1483
1484 int manager_acquire_key_pair(Manager *m) {
1485 int r;
1486
1487 assert(m);
1488
1489 /* Already there? */
1490 if (m->private_key)
1491 return 1;
1492
1493 /* First try to load key off disk */
1494 r = manager_load_key_pair(m);
1495 if (r != 0)
1496 return r;
1497
1498 /* Didn't work, generate a new one */
1499 return manager_generate_key_pair(m);
1500 }
1501
1502 int manager_sign_user_record(Manager *m, UserRecord *u, UserRecord **ret, sd_bus_error *error) {
1503 int r;
1504
1505 assert(m);
1506 assert(u);
1507 assert(ret);
1508
1509 r = manager_acquire_key_pair(m);
1510 if (r < 0)
1511 return r;
1512 if (r == 0)
1513 return sd_bus_error_set(error, BUS_ERROR_NO_PRIVATE_KEY, "Can't sign without local key.");
1514
1515 return user_record_sign(u, m->private_key, ret);
1516 }
1517
1518 DEFINE_PRIVATE_HASH_OPS_FULL(public_key_hash_ops, char, string_hash_func, string_compare_func, free, EVP_PKEY, EVP_PKEY_free);
1519
1520 static int manager_load_public_key_one(Manager *m, const char *path) {
1521 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
1522 _cleanup_fclose_ FILE *f = NULL;
1523 _cleanup_free_ char *fn = NULL;
1524 struct stat st;
1525 int r;
1526
1527 assert(m);
1528
1529 r = path_extract_filename(path, &fn);
1530 if (r < 0)
1531 return log_error_errno(r, "Failed to extract filename of path '%s': %m", path);
1532
1533 if (streq(fn, "local.public")) /* we already loaded the private key, which includes the public one */
1534 return 0;
1535
1536 f = fopen(path, "re");
1537 if (!f) {
1538 if (errno == ENOENT)
1539 return 0;
1540
1541 return log_error_errno(errno, "Failed to open public key %s: %m", path);
1542 }
1543
1544 if (fstat(fileno(f), &st) < 0)
1545 return log_error_errno(errno, "Failed to stat public key %s: %m", path);
1546
1547 r = stat_verify_regular(&st);
1548 if (r < 0)
1549 return log_error_errno(r, "Public key file %s is not a regular file: %m", path);
1550
1551 if (st.st_uid != 0 || (st.st_mode & 0022) != 0)
1552 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Public key file %s is writable by more than the root user, refusing.", path);
1553
1554 r = hashmap_ensure_allocated(&m->public_keys, &public_key_hash_ops);
1555 if (r < 0)
1556 return log_oom();
1557
1558 pkey = PEM_read_PUBKEY(f, &pkey, NULL, NULL);
1559 if (!pkey)
1560 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key file %s.", path);
1561
1562 r = hashmap_put(m->public_keys, fn, pkey);
1563 if (r < 0)
1564 return log_error_errno(r, "Failed to add public key to set: %m");
1565
1566 TAKE_PTR(fn);
1567 TAKE_PTR(pkey);
1568
1569 return 0;
1570 }
1571
1572 static int manager_load_public_keys(Manager *m) {
1573 _cleanup_strv_free_ char **files = NULL;
1574 int r;
1575
1576 assert(m);
1577
1578 m->public_keys = hashmap_free(m->public_keys);
1579
1580 r = conf_files_list_nulstr(
1581 &files,
1582 ".public",
1583 NULL,
1584 CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
1585 KEY_PATHS_NULSTR);
1586 if (r < 0)
1587 return log_error_errno(r, "Failed to assemble list of public key directories: %m");
1588
1589 STRV_FOREACH(i, files)
1590 (void) manager_load_public_key_one(m, *i);
1591
1592 return 0;
1593 }
1594
1595 int manager_startup(Manager *m) {
1596 int r;
1597
1598 assert(m);
1599
1600 r = manager_listen_notify(m);
1601 if (r < 0)
1602 return r;
1603
1604 r = manager_connect_bus(m);
1605 if (r < 0)
1606 return r;
1607
1608 r = manager_bind_varlink(m);
1609 if (r < 0)
1610 return r;
1611
1612 r = manager_load_key_pair(m); /* only try to load it, don't generate any */
1613 if (r < 0)
1614 return r;
1615
1616 r = manager_load_public_keys(m);
1617 if (r < 0)
1618 return r;
1619
1620 manager_watch_home(m);
1621 (void) manager_watch_devices(m);
1622
1623 (void) manager_enumerate_records(m);
1624 (void) manager_enumerate_images(m);
1625 (void) manager_enumerate_devices(m);
1626
1627 /* Let's clean up home directories whose devices got removed while we were not running */
1628 (void) manager_enqueue_gc(m, NULL);
1629
1630 return 0;
1631 }
1632
1633 void manager_revalidate_image(Manager *m, Home *h) {
1634 int r;
1635
1636 assert(m);
1637 assert(h);
1638
1639 /* Frees an automatically discovered image, if it's synthetic and its image disappeared. Unmounts any
1640 * image if it's mounted but its image vanished. */
1641
1642 if (h->current_operation || !ordered_set_isempty(h->pending_operations))
1643 return;
1644
1645 if (h->state == HOME_UNFIXATED) {
1646 r = user_record_test_image_path(h->record);
1647 if (r < 0)
1648 log_warning_errno(r, "Can't determine if image of %s exists, freeing unfixated user: %m", h->user_name);
1649 else if (r == USER_TEST_ABSENT)
1650 log_info("Image for %s disappeared, freeing unfixated user.", h->user_name);
1651 else
1652 return;
1653
1654 home_free(h);
1655
1656 } else if (h->state < 0) {
1657
1658 r = user_record_test_home_directory(h->record);
1659 if (r < 0) {
1660 log_warning_errno(r, "Unable to determine state of home directory, ignoring: %m");
1661 return;
1662 }
1663
1664 if (r == USER_TEST_MOUNTED) {
1665 r = user_record_test_image_path(h->record);
1666 if (r < 0) {
1667 log_warning_errno(r, "Unable to determine state of image path, ignoring: %m");
1668 return;
1669 }
1670
1671 if (r == USER_TEST_ABSENT) {
1672 _cleanup_(operation_unrefp) Operation *o = NULL;
1673
1674 log_notice("Backing image disappeared while home directory %s was mounted, unmounting it forcibly.", h->user_name);
1675 /* Wowza, the thing is mounted, but the device is gone? Act on it. */
1676
1677 r = home_killall(h);
1678 if (r < 0)
1679 log_warning_errno(r, "Failed to kill processes of user %s, ignoring: %m", h->user_name);
1680
1681 /* We enqueue the operation here, after all the home directory might
1682 * currently already run some operation, and we can deactivate it only after
1683 * that's complete. */
1684 o = operation_new(OPERATION_DEACTIVATE_FORCE, NULL);
1685 if (!o) {
1686 log_oom();
1687 return;
1688 }
1689
1690 r = home_schedule_operation(h, o, NULL);
1691 if (r < 0)
1692 log_warning_errno(r, "Failed to enqueue forced home directory %s deactivation, ignoring: %m", h->user_name);
1693 }
1694 }
1695 }
1696 }
1697
1698 int manager_gc_images(Manager *m) {
1699 Home *h;
1700
1701 assert_se(m);
1702
1703 if (m->gc_focus) {
1704 /* Focus on a specific home */
1705
1706 h = TAKE_PTR(m->gc_focus);
1707 manager_revalidate_image(m, h);
1708 } else {
1709 /* Gc all */
1710
1711 HASHMAP_FOREACH(h, m->homes_by_name)
1712 manager_revalidate_image(m, h);
1713 }
1714
1715 return 0;
1716 }
1717
1718 static int on_deferred_rescan(sd_event_source *s, void *userdata) {
1719 Manager *m = ASSERT_PTR(userdata);
1720
1721 m->deferred_rescan_event_source = sd_event_source_disable_unref(m->deferred_rescan_event_source);
1722
1723 manager_enumerate_devices(m);
1724 manager_enumerate_images(m);
1725 return 0;
1726 }
1727
1728 int manager_enqueue_rescan(Manager *m) {
1729 int r;
1730
1731 assert(m);
1732
1733 if (m->deferred_rescan_event_source)
1734 return 0;
1735
1736 if (!m->event)
1737 return 0;
1738
1739 if (IN_SET(sd_event_get_state(m->event), SD_EVENT_FINISHED, SD_EVENT_EXITING))
1740 return 0;
1741
1742 r = sd_event_add_defer(m->event, &m->deferred_rescan_event_source, on_deferred_rescan, m);
1743 if (r < 0)
1744 return log_error_errno(r, "Failed to allocate rescan event source: %m");
1745
1746 r = sd_event_source_set_priority(m->deferred_rescan_event_source, SD_EVENT_PRIORITY_IDLE+1);
1747 if (r < 0)
1748 log_warning_errno(r, "Failed to tweak priority of event source, ignoring: %m");
1749
1750 (void) sd_event_source_set_description(m->deferred_rescan_event_source, "deferred-rescan");
1751 return 1;
1752 }
1753
1754 static int on_deferred_gc(sd_event_source *s, void *userdata) {
1755 Manager *m = ASSERT_PTR(userdata);
1756
1757 m->deferred_gc_event_source = sd_event_source_disable_unref(m->deferred_gc_event_source);
1758
1759 manager_gc_images(m);
1760 return 0;
1761 }
1762
1763 int manager_enqueue_gc(Manager *m, Home *focus) {
1764 int r;
1765
1766 assert(m);
1767
1768 /* This enqueues a request to GC dead homes. It may be called with focus=NULL in which case all homes
1769 * will be scanned, or with the parameter set, in which case only that home is checked. */
1770
1771 if (!m->event)
1772 return 0;
1773
1774 if (IN_SET(sd_event_get_state(m->event), SD_EVENT_FINISHED, SD_EVENT_EXITING))
1775 return 0;
1776
1777 /* If a focus home is specified, then remember to focus just on this home. Otherwise invalidate any
1778 * focus that might be set to look at all homes. */
1779
1780 if (m->deferred_gc_event_source) {
1781 if (m->gc_focus != focus) /* not the same focus, then look at everything */
1782 m->gc_focus = NULL;
1783
1784 return 0;
1785 } else
1786 m->gc_focus = focus; /* start focused */
1787
1788 r = sd_event_add_defer(m->event, &m->deferred_gc_event_source, on_deferred_gc, m);
1789 if (r < 0)
1790 return log_error_errno(r, "Failed to allocate GC event source: %m");
1791
1792 r = sd_event_source_set_priority(m->deferred_gc_event_source, SD_EVENT_PRIORITY_IDLE);
1793 if (r < 0)
1794 log_warning_errno(r, "Failed to tweak priority of event source, ignoring: %m");
1795
1796 (void) sd_event_source_set_description(m->deferred_gc_event_source, "deferred-gc");
1797 return 1;
1798 }
1799
1800 static bool manager_shall_rebalance(Manager *m) {
1801 Home *h;
1802
1803 assert(m);
1804
1805 if (IN_SET(m->rebalance_state, REBALANCE_PENDING, REBALANCE_SHRINKING, REBALANCE_GROWING))
1806 return true;
1807
1808 HASHMAP_FOREACH(h, m->homes_by_name)
1809 if (home_shall_rebalance(h))
1810 return true;
1811
1812 return false;
1813 }
1814
1815 static int home_cmp(Home *const*a, Home *const*b) {
1816 int r;
1817
1818 assert(a);
1819 assert(*a);
1820 assert(b);
1821 assert(*b);
1822
1823 /* Order user records by their weight (and by their name, to make things stable). We put the records
1824 * with the highest weight last, since we distribute space from the beginning and round down, hence
1825 * later entries tend to get slightly more than earlier entries. */
1826
1827 r = CMP(user_record_rebalance_weight((*a)->record), user_record_rebalance_weight((*b)->record));
1828 if (r != 0)
1829 return r;
1830
1831 return strcmp((*a)->user_name, (*b)->user_name);
1832 }
1833
1834 static int manager_rebalance_calculate(Manager *m) {
1835 uint64_t weight_sum, free_sum, usage_sum = 0, min_free = UINT64_MAX;
1836 _cleanup_free_ Home **array = NULL;
1837 bool relevant = false;
1838 struct statfs sfs;
1839 int c = 0, r;
1840 Home *h;
1841
1842 assert(m);
1843
1844 if (statfs(get_home_root(), &sfs) < 0)
1845 return log_error_errno(errno, "Failed to statfs() /home: %m");
1846
1847 free_sum = (uint64_t) sfs.f_bsize * sfs.f_bavail; /* This much free space is available on the
1848 * underlying pool directory */
1849
1850 weight_sum = REBALANCE_WEIGHT_BACKING; /* Grant the underlying pool directory a fixed weight of 20
1851 * (home dirs get 100 by default, i.e. 5x more). This weight
1852 * is not configurable, the per-home weights are. */
1853
1854 HASHMAP_FOREACH(h, m->homes_by_name) {
1855 statfs_f_type_t fstype;
1856 h->rebalance_pending = false; /* First, reset the flag, we only want it to be true for the
1857 * homes that qualify for rebalancing */
1858
1859 if (!home_shall_rebalance(h)) /* Only look at actual candidates */
1860 continue;
1861
1862 if (home_is_busy(h))
1863 return -EBUSY; /* Let's not rebalance if there's a busy home directory. */
1864
1865 r = home_get_disk_status(
1866 h,
1867 &h->rebalance_size,
1868 &h->rebalance_usage,
1869 &h->rebalance_free,
1870 NULL,
1871 NULL,
1872 &fstype,
1873 NULL);
1874 if (r < 0) {
1875 log_warning_errno(r, "Failed to get free space of home '%s', ignoring.", h->user_name);
1876 continue;
1877 }
1878
1879 if (h->rebalance_free > UINT64_MAX - free_sum)
1880 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Rebalance free overflow");
1881 free_sum += h->rebalance_free;
1882
1883 if (h->rebalance_usage > UINT64_MAX - usage_sum)
1884 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Rebalance usage overflow");
1885 usage_sum += h->rebalance_usage;
1886
1887 h->rebalance_weight = user_record_rebalance_weight(h->record);
1888 if (h->rebalance_weight > UINT64_MAX - weight_sum)
1889 return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Rebalance weight overflow");
1890 weight_sum += h->rebalance_weight;
1891
1892 h->rebalance_min = minimal_size_by_fs_magic(fstype);
1893
1894 if (!GREEDY_REALLOC(array, c+1))
1895 return log_oom();
1896
1897 array[c++] = h;
1898 }
1899
1900 if (c == 0) {
1901 log_debug("No homes to rebalance.");
1902 return 0;
1903 }
1904
1905 assert(weight_sum > 0);
1906
1907 log_debug("Disk space usage by all home directories to rebalance: %s — available disk space: %s",
1908 FORMAT_BYTES(usage_sum), FORMAT_BYTES(free_sum));
1909
1910 /* Bring the home directories in a well-defined order, so that we distribute space in a reproducible
1911 * way for the same parameters. */
1912 typesafe_qsort(array, c, home_cmp);
1913
1914 for (int i = 0; i < c; i++) {
1915 uint64_t new_free;
1916 double d;
1917
1918 h = array[i];
1919
1920 assert(h->rebalance_free <= free_sum);
1921 assert(h->rebalance_usage <= usage_sum);
1922 assert(h->rebalance_weight <= weight_sum);
1923
1924 d = ((double) (free_sum / 4096) * (double) h->rebalance_weight) / (double) weight_sum; /* Calculate new space for this home in units of 4K */
1925
1926 /* Convert from units of 4K back to bytes */
1927 if (d >= (double) (UINT64_MAX/4096))
1928 new_free = UINT64_MAX;
1929 else
1930 new_free = (uint64_t) d * 4096;
1931
1932 /* Subtract the weight and assigned space from the sums now, to distribute the rounding noise
1933 * to the remaining home dirs */
1934 free_sum = LESS_BY(free_sum, new_free);
1935 weight_sum = LESS_BY(weight_sum, h->rebalance_weight);
1936
1937 /* Keep track of home directory with the least amount of space left: we want to schedule the
1938 * next rebalance more quickly if this is low */
1939 if (new_free < min_free)
1940 min_free = h->rebalance_size;
1941
1942 if (new_free > UINT64_MAX - h->rebalance_usage)
1943 h->rebalance_goal = UINT64_MAX-1; /* maximum size */
1944 else {
1945 h->rebalance_goal = h->rebalance_usage + new_free;
1946
1947 if (h->rebalance_min != UINT64_MAX && h->rebalance_goal < h->rebalance_min)
1948 h->rebalance_goal = h->rebalance_min;
1949 }
1950
1951 /* Skip over this home if the state doesn't match the operation */
1952 if ((m->rebalance_state == REBALANCE_SHRINKING && h->rebalance_goal > h->rebalance_size) ||
1953 (m->rebalance_state == REBALANCE_GROWING && h->rebalance_goal < h->rebalance_size))
1954 h->rebalance_pending = false;
1955 else {
1956 log_debug("Rebalancing home directory '%s' %s %s %s.", h->user_name,
1957 FORMAT_BYTES(h->rebalance_size),
1958 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT),
1959 FORMAT_BYTES(h->rebalance_goal));
1960 h->rebalance_pending = true;
1961 }
1962
1963 if ((fabs((double) h->rebalance_size - (double) h->rebalance_goal) * 100 / (double) h->rebalance_size) >= 5.0)
1964 relevant = true;
1965 }
1966
1967 /* Scale next rebalancing interval based on the least amount of space of any of the home
1968 * directories. We pick a time in the range 1min … 15min, scaled by log2(min_free), so that:
1969 * 10M → ~0.7min, 100M → ~2.7min, 1G → ~4.6min, 10G → ~6.5min, 100G ~8.4 */
1970 m->rebalance_interval_usec = (usec_t) CLAMP((LESS_BY(log2(min_free), 22)*15*USEC_PER_MINUTE)/26,
1971 1 * USEC_PER_MINUTE,
1972 15 * USEC_PER_MINUTE);
1973
1974
1975 log_debug("Rebalancing interval set to %s.", FORMAT_TIMESPAN(m->rebalance_interval_usec, USEC_PER_MSEC));
1976
1977 /* Let's suppress small resizes, growing/shrinking file systems isn't free after all */
1978 if (!relevant) {
1979 log_debug("Skipping rebalancing, since all calculated size changes are below ±5%%.");
1980 return 0;
1981 }
1982
1983 return c;
1984 }
1985
1986 static int manager_rebalance_apply(Manager *m) {
1987 int c = 0, r;
1988 Home *h;
1989
1990 assert(m);
1991
1992 HASHMAP_FOREACH(h, m->homes_by_name) {
1993 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1994
1995 if (!h->rebalance_pending)
1996 continue;
1997
1998 h->rebalance_pending = false;
1999
2000 r = home_resize(h, h->rebalance_goal, /* secret= */ NULL, /* automatic= */ true, &error);
2001 if (r < 0)
2002 log_warning_errno(r, "Failed to resize home '%s' for rebalancing, ignoring: %s",
2003 h->user_name, bus_error_message(&error, r));
2004 else
2005 c++;
2006 }
2007
2008 return c;
2009 }
2010
2011 static void manager_rebalance_reply_messages(Manager *m) {
2012 int r;
2013
2014 assert(m);
2015
2016 for (;;) {
2017 _cleanup_(sd_bus_message_unrefp) sd_bus_message *msg =
2018 set_steal_first(m->rebalance_pending_method_calls);
2019
2020 if (!msg)
2021 break;
2022
2023 r = sd_bus_reply_method_return(msg, NULL);
2024 if (r < 0)
2025 log_debug_errno(r, "Failed to reply to rebalance method call, ignoring: %m");
2026 }
2027 }
2028
2029 static int manager_rebalance_now(Manager *m) {
2030 RebalanceState busy_state; /* the state to revert to when operation fails if busy */
2031 int r;
2032
2033 assert(m);
2034
2035 log_debug("Rebalancing now...");
2036
2037 /* We maintain a simple state engine here to keep track of what we are doing. We'll first shrink all
2038 * homes that shall be shrunk and then grow all homes that shall be grown, so that they can take up
2039 * the space now freed. */
2040
2041 for (;;) {
2042 switch (m->rebalance_state) {
2043
2044 case REBALANCE_IDLE:
2045 case REBALANCE_PENDING:
2046 case REBALANCE_WAITING:
2047 /* First shrink large home dirs */
2048 m->rebalance_state = REBALANCE_SHRINKING;
2049 busy_state = REBALANCE_PENDING;
2050
2051 /* We are initiating the next rebalancing cycle now, let's make the queued methods
2052 * calls the pending ones, and flush out any pending ones (which shouldn't exist at
2053 * this time anyway) */
2054 set_clear(m->rebalance_pending_method_calls);
2055 SWAP_TWO(m->rebalance_pending_method_calls, m->rebalance_queued_method_calls);
2056
2057 log_debug("Shrinking phase..");
2058 break;
2059
2060 case REBALANCE_SHRINKING:
2061 /* Then grow small home dirs */
2062 m->rebalance_state = REBALANCE_GROWING;
2063 busy_state = REBALANCE_SHRINKING;
2064 log_debug("Growing phase..");
2065 break;
2066
2067 case REBALANCE_GROWING:
2068 /* Finally, we are done */
2069 log_info("Rebalancing complete.");
2070 m->rebalance_state = REBALANCE_IDLE;
2071 r = 0;
2072 goto finish;
2073
2074 case REBALANCE_OFF:
2075 default:
2076 assert_not_reached();
2077 }
2078
2079 r = manager_rebalance_calculate(m);
2080 if (r == -EBUSY) {
2081 /* Calculations failed because one home directory is currently busy. Revert to a state that
2082 * tells us what to do next. */
2083 log_debug("Can't enter phase, busy.");
2084 m->rebalance_state = busy_state;
2085 return r;
2086 }
2087 if (r < 0)
2088 goto finish;
2089 if (r == 0)
2090 continue; /* got to next step immediately, if there's nothing to do */
2091
2092 r = manager_rebalance_apply(m);
2093 if (r < 0)
2094 goto finish;
2095 if (r > 0)
2096 break; /* At least one resize operation is now pending, we are done for now */
2097
2098 /* If there was nothing to apply, go for next state right-away */
2099 }
2100
2101 return 0;
2102
2103 finish:
2104 /* Reset state and schedule next rebalance */
2105 m->rebalance_state = REBALANCE_IDLE;
2106 manager_rebalance_reply_messages(m);
2107 (void) manager_schedule_rebalance(m, /* immediately= */ false);
2108 return r;
2109 }
2110
2111 static int on_rebalance_timer(sd_event_source *s, usec_t t, void *userdata) {
2112 Manager *m = ASSERT_PTR(userdata);
2113
2114 assert(s);
2115 assert(IN_SET(m->rebalance_state, REBALANCE_WAITING, REBALANCE_PENDING, REBALANCE_SHRINKING, REBALANCE_GROWING));
2116
2117 (void) manager_rebalance_now(m);
2118 return 0;
2119 }
2120
2121 int manager_schedule_rebalance(Manager *m, bool immediately) {
2122 int r;
2123
2124 assert(m);
2125
2126 /* Check if there are any records where rebalancing is requested */
2127 if (!manager_shall_rebalance(m)) {
2128 log_debug("Not scheduling rebalancing, not needed.");
2129 r = 0; /* report that we didn't schedule anything because nothing needed it */
2130 goto turn_off;
2131 }
2132
2133 if (immediately) {
2134 /* If we are told to rebalance immediately, then mark a rebalance as pending (even if we area
2135 * already running one) */
2136
2137 if (m->rebalance_event_source) {
2138 r = sd_event_source_set_time(m->rebalance_event_source, 0);
2139 if (r < 0) {
2140 log_error_errno(r, "Failed to schedule immediate rebalancing: %m");
2141 goto turn_off;
2142 }
2143
2144 r = sd_event_source_set_enabled(m->rebalance_event_source, SD_EVENT_ONESHOT);
2145 if (r < 0) {
2146 log_error_errno(r, "Failed to enable rebalancing event source: %m");
2147 goto turn_off;
2148 }
2149 } else {
2150 r = sd_event_add_time(m->event, &m->rebalance_event_source, CLOCK_MONOTONIC, 0, USEC_PER_SEC, on_rebalance_timer, m);
2151 if (r < 0) {
2152 log_error_errno(r, "Failed to allocate rebalance event source: %m");
2153 goto turn_off;
2154 }
2155
2156 r = sd_event_source_set_priority(m->rebalance_event_source, SD_EVENT_PRIORITY_IDLE + 10);
2157 if (r < 0) {
2158 log_error_errno(r, "Failed to set rebalance event source priority: %m");
2159 goto turn_off;
2160 }
2161
2162 (void) sd_event_source_set_description(m->rebalance_event_source, "rebalance");
2163
2164 }
2165
2166 if (!IN_SET(m->rebalance_state, REBALANCE_PENDING, REBALANCE_SHRINKING, REBALANCE_GROWING))
2167 m->rebalance_state = REBALANCE_PENDING;
2168
2169 log_debug("Scheduled immediate rebalancing...");
2170 return 1; /* report that we scheduled something */
2171 }
2172
2173 /* If we are told to schedule a rebalancing eventually, then do so only if we are not executing
2174 * anything yet. Also if we have something scheduled already, leave it in place */
2175 if (!IN_SET(m->rebalance_state, REBALANCE_OFF, REBALANCE_IDLE))
2176 return 1; /* report that there's already something scheduled */
2177
2178 if (m->rebalance_event_source) {
2179 r = sd_event_source_set_time_relative(m->rebalance_event_source, m->rebalance_interval_usec);
2180 if (r < 0) {
2181 log_error_errno(r, "Failed to schedule immediate rebalancing: %m");
2182 goto turn_off;
2183 }
2184
2185 r = sd_event_source_set_enabled(m->rebalance_event_source, SD_EVENT_ONESHOT);
2186 if (r < 0) {
2187 log_error_errno(r, "Failed to enable rebalancing event source: %m");
2188 goto turn_off;
2189 }
2190 } else {
2191 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);
2192 if (r < 0) {
2193 log_error_errno(r, "Failed to allocate rebalance event source: %m");
2194 goto turn_off;
2195 }
2196
2197 r = sd_event_source_set_priority(m->rebalance_event_source, SD_EVENT_PRIORITY_IDLE + 10);
2198 if (r < 0) {
2199 log_error_errno(r, "Failed to set rebalance event source priority: %m");
2200 goto turn_off;
2201 }
2202
2203 (void) sd_event_source_set_description(m->rebalance_event_source, "rebalance");
2204 }
2205
2206 m->rebalance_state = REBALANCE_WAITING; /* We managed to enqueue a timer event, we now wait until it fires */
2207 log_debug("Scheduled rebalancing in %s...", FORMAT_TIMESPAN(m->rebalance_interval_usec, 0));
2208 return 1; /* report that we scheduled something */
2209
2210 turn_off:
2211 m->rebalance_event_source = sd_event_source_disable_unref(m->rebalance_event_source);
2212 m->rebalance_state = REBALANCE_OFF;
2213 manager_rebalance_reply_messages(m);
2214 return r;
2215 }
2216
2217 int manager_reschedule_rebalance(Manager *m) {
2218 int r;
2219
2220 assert(m);
2221
2222 /* If a rebalance is pending reschedules it so it gets executed immediately */
2223
2224 if (!IN_SET(m->rebalance_state, REBALANCE_PENDING, REBALANCE_SHRINKING, REBALANCE_GROWING))
2225 return 0;
2226
2227 r = manager_schedule_rebalance(m, /* immediately= */ true);
2228 if (r < 0)
2229 return r;
2230
2231 return 1;
2232 }