]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/home/homed-manager.c
Merge pull request #21487 from DaanDeMeyer/dissect-image-other-arch
[thirdparty/systemd.git] / src / home / homed-manager.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
70a5db58
LP
2
3#include <grp.h>
4#include <linux/fs.h>
5#include <linux/magic.h>
6#include <openssl/pem.h>
7#include <pwd.h>
8#include <sys/ioctl.h>
9#include <sys/quota.h>
10#include <sys/stat.h>
11
12#include "btrfs-util.h"
13#include "bus-common-errors.h"
14#include "bus-error.h"
ac9f55ed 15#include "bus-log-control-api.h"
70a5db58
LP
16#include "bus-polkit.h"
17#include "clean-ipc.h"
18#include "conf-files.h"
19#include "device-util.h"
20#include "dirent-util.h"
21#include "fd-util.h"
22#include "fileio.h"
23#include "format-util.h"
24#include "fs-util.h"
25#include "gpt.h"
26#include "home-util.h"
c76dd733 27#include "homed-conf.h"
70a5db58
LP
28#include "homed-home-bus.h"
29#include "homed-home.h"
30#include "homed-manager-bus.h"
31#include "homed-manager.h"
32#include "homed-varlink.h"
33#include "io-util.h"
34#include "mkdir.h"
35#include "process-util.h"
36#include "quota-util.h"
37#include "random-util.h"
38#include "socket-util.h"
39#include "stat-util.h"
40#include "strv.h"
bf819d3a 41#include "sync-util.h"
70a5db58
LP
42#include "tmpfile-util.h"
43#include "udev-util.h"
44#include "user-record-sign.h"
45#include "user-record-util.h"
46#include "user-record.h"
47#include "user-util.h"
48
49/* Where to look for private/public keys that are used to sign the user records. We are not using
50 * CONF_PATHS_NULSTR() here since we want to insert /var/lib/systemd/home/ in the middle. And we insert that
51 * since we want to auto-generate a persistent private/public key pair if we need to. */
52#define KEY_PATHS_NULSTR \
53 "/etc/systemd/home/\0" \
54 "/run/systemd/home/\0" \
55 "/var/lib/systemd/home/\0" \
56 "/usr/local/lib/systemd/home/\0" \
57 "/usr/lib/systemd/home/\0"
58
59static bool uid_is_home(uid_t uid) {
60 return uid >= HOME_UID_MIN && uid <= HOME_UID_MAX;
61}
62/* Takes a value generated randomly or by hashing and turns it into a UID in the right range */
63
64#define UID_CLAMP_INTO_HOME_RANGE(rnd) (((uid_t) (rnd) % (HOME_UID_MAX - HOME_UID_MIN + 1)) + HOME_UID_MIN)
65
66DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_uid_hash_ops, void, trivial_hash_func, trivial_compare_func, Home, home_free);
67DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_name_hash_ops, char, string_hash_func, string_compare_func, Home, home_free);
68DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_worker_pid_hash_ops, void, trivial_hash_func, trivial_compare_func, Home, home_free);
69DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_sysfs_hash_ops, char, path_hash_func, path_compare, Home, home_free);
70
71static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata);
72static int manager_gc_images(Manager *m);
73static int manager_enumerate_images(Manager *m);
74static int manager_assess_image(Manager *m, int dir_fd, const char *dir_path, const char *dentry_name);
75static void manager_revalidate_image(Manager *m, Home *h);
76
77static void manager_watch_home(Manager *m) {
78 struct statfs sfs;
79 int r;
80
81 assert(m);
82
cf536638 83 m->inotify_event_source = sd_event_source_disable_unref(m->inotify_event_source);
70a5db58
LP
84 m->scan_slash_home = false;
85
2700fecd 86 if (statfs(get_home_root(), &sfs) < 0) {
70a5db58 87 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
2700fecd 88 "Failed to statfs() %s directory, disabling automatic scanning.", get_home_root());
70a5db58
LP
89 return;
90 }
91
92 if (is_network_fs(&sfs)) {
2700fecd 93 log_info("%s is a network file system, disabling automatic scanning.", get_home_root());
70a5db58
LP
94 return;
95 }
96
97 if (is_fs_type(&sfs, AUTOFS_SUPER_MAGIC)) {
2700fecd 98 log_info("%s is on autofs, disabling automatic scanning.", get_home_root());
70a5db58
LP
99 return;
100 }
101
102 m->scan_slash_home = true;
103
2700fecd 104 r = sd_event_add_inotify(m->event, &m->inotify_event_source, get_home_root(),
23d24b76
ZJS
105 IN_CREATE|IN_CLOSE_WRITE|IN_DELETE_SELF|IN_MOVE_SELF|IN_ONLYDIR|IN_MOVED_TO|IN_MOVED_FROM|IN_DELETE,
106 on_home_inotify, m);
70a5db58
LP
107 if (r < 0)
108 log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
2700fecd 109 "Failed to create inotify watch on %s, ignoring.", get_home_root());
70a5db58
LP
110
111 (void) sd_event_source_set_description(m->inotify_event_source, "home-inotify");
2700fecd
LP
112
113 log_info("Watching %s.", get_home_root());
70a5db58
LP
114}
115
116static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata) {
2700fecd 117 _cleanup_free_ char *j = NULL;
70a5db58
LP
118 Manager *m = userdata;
119 const char *e, *n;
120
121 assert(m);
122 assert(event);
123
124 if ((event->mask & (IN_Q_OVERFLOW|IN_MOVE_SELF|IN_DELETE_SELF|IN_IGNORED|IN_UNMOUNT)) != 0) {
125
126 if (FLAGS_SET(event->mask, IN_Q_OVERFLOW))
2700fecd 127 log_debug("%s inotify queue overflow, rescanning.", get_home_root());
70a5db58 128 else if (FLAGS_SET(event->mask, IN_MOVE_SELF))
2700fecd 129 log_info("%s moved or renamed, recreating watch and rescanning.", get_home_root());
70a5db58 130 else if (FLAGS_SET(event->mask, IN_DELETE_SELF))
2700fecd 131 log_info("%s deleted, recreating watch and rescanning.", get_home_root());
70a5db58 132 else if (FLAGS_SET(event->mask, IN_UNMOUNT))
2700fecd 133 log_info("%s unmounted, recreating watch and rescanning.", get_home_root());
70a5db58 134 else if (FLAGS_SET(event->mask, IN_IGNORED))
2700fecd 135 log_info("%s watch invalidated, recreating watch and rescanning.", get_home_root());
70a5db58
LP
136
137 manager_watch_home(m);
138 (void) manager_gc_images(m);
139 (void) manager_enumerate_images(m);
140 (void) bus_manager_emit_auto_login_changed(m);
141 return 0;
142 }
143
144 /* For the other inotify events, let's ignore all events for file names that don't match our
145 * expectations */
146 if (isempty(event->name))
147 return 0;
148 e = endswith(event->name, FLAGS_SET(event->mask, IN_ISDIR) ? ".homedir" : ".home");
149 if (!e)
150 return 0;
151
2f82562b 152 n = strndupa_safe(event->name, e - event->name);
70a5db58
LP
153 if (!suitable_user_name(n))
154 return 0;
155
2700fecd
LP
156 j = path_join(get_home_root(), event->name);
157 if (!j)
158 return log_oom();
159
70a5db58
LP
160 if ((event->mask & (IN_CREATE|IN_CLOSE_WRITE|IN_MOVED_TO)) != 0) {
161 if (FLAGS_SET(event->mask, IN_CREATE))
2700fecd 162 log_debug("%s has been created, having a look.", j);
70a5db58 163 else if (FLAGS_SET(event->mask, IN_CLOSE_WRITE))
2700fecd 164 log_debug("%s has been modified, having a look.", j);
70a5db58 165 else if (FLAGS_SET(event->mask, IN_MOVED_TO))
2700fecd 166 log_debug("%s has been moved in, having a look.", j);
70a5db58 167
2700fecd 168 (void) manager_assess_image(m, -1, get_home_root(), event->name);
70a5db58
LP
169 (void) bus_manager_emit_auto_login_changed(m);
170 }
171
755b35b1 172 if ((event->mask & (IN_DELETE | IN_CLOSE_WRITE | IN_MOVED_FROM)) != 0) {
70a5db58
LP
173 Home *h;
174
175 if (FLAGS_SET(event->mask, IN_DELETE))
2700fecd 176 log_debug("%s has been deleted, revalidating.", j);
70a5db58 177 else if (FLAGS_SET(event->mask, IN_CLOSE_WRITE))
2700fecd 178 log_debug("%s has been closed after writing, revalidating.", j);
70a5db58 179 else if (FLAGS_SET(event->mask, IN_MOVED_FROM))
2700fecd 180 log_debug("%s has been moved away, revalidating.", j);
70a5db58
LP
181
182 h = hashmap_get(m->homes_by_name, n);
183 if (h) {
184 manager_revalidate_image(m, h);
185 (void) bus_manager_emit_auto_login_changed(m);
186 }
187 }
188
189 return 0;
190}
191
192int manager_new(Manager **ret) {
193 _cleanup_(manager_freep) Manager *m = NULL;
194 int r;
195
196 assert(ret);
197
c76dd733 198 m = new(Manager, 1);
70a5db58
LP
199 if (!m)
200 return -ENOMEM;
201
c76dd733
LP
202 *m = (Manager) {
203 .default_storage = _USER_STORAGE_INVALID,
204 };
205
206 r = manager_parse_config_file(m);
207 if (r < 0)
208 return r;
209
70a5db58
LP
210 r = sd_event_default(&m->event);
211 if (r < 0)
212 return r;
213
214 r = sd_event_add_signal(m->event, NULL, SIGINT, NULL, NULL);
215 if (r < 0)
216 return r;
217
218 r = sd_event_add_signal(m->event, NULL, SIGTERM, NULL, NULL);
219 if (r < 0)
220 return r;
221
222 (void) sd_event_set_watchdog(m->event, true);
223
224 m->homes_by_uid = hashmap_new(&homes_by_uid_hash_ops);
225 if (!m->homes_by_uid)
226 return -ENOMEM;
227
228 m->homes_by_name = hashmap_new(&homes_by_name_hash_ops);
229 if (!m->homes_by_name)
230 return -ENOMEM;
231
232 m->homes_by_worker_pid = hashmap_new(&homes_by_worker_pid_hash_ops);
233 if (!m->homes_by_worker_pid)
234 return -ENOMEM;
235
236 m->homes_by_sysfs = hashmap_new(&homes_by_sysfs_hash_ops);
237 if (!m->homes_by_sysfs)
238 return -ENOMEM;
239
240 *ret = TAKE_PTR(m);
241 return 0;
242}
243
244Manager* manager_free(Manager *m) {
9796a9fb
LP
245 Home *h;
246
70a5db58
LP
247 assert(m);
248
9796a9fb
LP
249 HASHMAP_FOREACH(h, m->homes_by_worker_pid)
250 (void) home_wait_for_worker(h);
251
70a5db58 252 sd_bus_flush_close_unref(m->bus);
f76e5644 253 bus_verify_polkit_async_registry_free(m->polkit_registry);
70a5db58 254
70a5db58
LP
255 m->device_monitor = sd_device_monitor_unref(m->device_monitor);
256
f76e5644
ZJS
257 m->inotify_event_source = sd_event_source_unref(m->inotify_event_source);
258 m->notify_socket_event_source = sd_event_source_unref(m->notify_socket_event_source);
70a5db58
LP
259 m->deferred_rescan_event_source = sd_event_source_unref(m->deferred_rescan_event_source);
260 m->deferred_gc_event_source = sd_event_source_unref(m->deferred_gc_event_source);
261 m->deferred_auto_login_event_source = sd_event_source_unref(m->deferred_auto_login_event_source);
262
f76e5644
ZJS
263 sd_event_unref(m->event);
264
265 hashmap_free(m->homes_by_uid);
266 hashmap_free(m->homes_by_name);
267 hashmap_free(m->homes_by_worker_pid);
268 hashmap_free(m->homes_by_sysfs);
269
70a5db58
LP
270 if (m->private_key)
271 EVP_PKEY_free(m->private_key);
272
273 hashmap_free(m->public_keys);
274
275 varlink_server_unref(m->varlink_server);
cc9886bc 276 free(m->userdb_service);
70a5db58 277
c76dd733
LP
278 free(m->default_file_system_type);
279
70a5db58
LP
280 return mfree(m);
281}
282
283int manager_verify_user_record(Manager *m, UserRecord *hr) {
284 EVP_PKEY *pkey;
70a5db58
LP
285 int r;
286
287 assert(m);
288 assert(hr);
289
290 if (!m->private_key && hashmap_isempty(m->public_keys)) {
291 r = user_record_has_signature(hr);
292 if (r < 0)
293 return r;
294
295 return r ? -ENOKEY : USER_RECORD_UNSIGNED;
296 }
297
298 /* Is it our own? */
299 if (m->private_key) {
300 r = user_record_verify(hr, m->private_key);
301 switch (r) {
302
303 case USER_RECORD_FOREIGN:
304 /* This record is not signed by this key, but let's see below */
305 break;
306
307 case USER_RECORD_SIGNED: /* Signed by us, but also by others, let's propagate that */
308 case USER_RECORD_SIGNED_EXCLUSIVE: /* Signed by us, and nothing else, ditto */
309 case USER_RECORD_UNSIGNED: /* Not signed at all, ditto */
310 default:
311 return r;
312 }
313 }
314
90e74a66 315 HASHMAP_FOREACH(pkey, m->public_keys) {
70a5db58
LP
316 r = user_record_verify(hr, pkey);
317 switch (r) {
318
319 case USER_RECORD_FOREIGN:
320 /* This record is not signed by this key, but let's see our other keys */
321 break;
322
323 case USER_RECORD_SIGNED: /* It's signed by this key we are happy with, but which is not our own. */
324 case USER_RECORD_SIGNED_EXCLUSIVE:
325 return USER_RECORD_FOREIGN;
326
327 case USER_RECORD_UNSIGNED: /* It's not signed at all */
328 default:
329 return r;
330 }
331 }
332
333 return -ENOKEY;
334}
335
336static int manager_add_home_by_record(
337 Manager *m,
338 const char *name,
339 int dir_fd,
340 const char *fname) {
341
342 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
852640f8 343 _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
70a5db58
LP
344 unsigned line, column;
345 int r, is_signed;
20f4a308 346 struct stat st;
70a5db58
LP
347 Home *h;
348
349 assert(m);
350 assert(name);
351 assert(fname);
352
20f4a308
LP
353 if (fstatat(dir_fd, fname, &st, 0) < 0)
354 return log_error_errno(errno, "Failed to stat identity record %s: %m", fname);
355
356 if (!S_ISREG(st.st_mode)) {
357 log_debug("Identity record file %s is not a regular file, ignoring.", fname);
358 return 0;
359 }
360
361 if (st.st_size == 0)
362 goto unlink_this_file;
363
70a5db58
LP
364 r = json_parse_file_at(NULL, dir_fd, fname, JSON_PARSE_SENSITIVE, &v, &line, &column);
365 if (r < 0)
366 return log_error_errno(r, "Failed to parse identity record at %s:%u%u: %m", fname, line, column);
367
20f4a308
LP
368 if (json_variant_is_blank_object(v))
369 goto unlink_this_file;
370
70a5db58
LP
371 hr = user_record_new();
372 if (!hr)
373 return log_oom();
374
bfc0cc1a 375 r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
70a5db58
LP
376 if (r < 0)
377 return r;
378
379 if (!streq_ptr(hr->user_name, name))
23d24b76
ZJS
380 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
381 "Identity's user name %s does not match file name %s, refusing.",
382 hr->user_name, name);
70a5db58
LP
383
384 is_signed = manager_verify_user_record(m, hr);
385 switch (is_signed) {
386
387 case -ENOKEY:
388 return log_warning_errno(is_signed, "User record %s is not signed by any accepted key, ignoring.", fname);
389 case USER_RECORD_UNSIGNED:
390 return log_warning_errno(SYNTHETIC_ERRNO(EPERM), "User record %s is not signed at all, ignoring.", fname);
391 case USER_RECORD_SIGNED:
392 log_info("User record %s is signed by us (and others), accepting.", fname);
393 break;
394 case USER_RECORD_SIGNED_EXCLUSIVE:
395 log_info("User record %s is signed only by us, accepting.", fname);
396 break;
397 case USER_RECORD_FOREIGN:
398 log_info("User record %s is signed by registered key from others, accepting.", fname);
399 break;
400 default:
401 assert(is_signed < 0);
402 return log_error_errno(is_signed, "Failed to verify signature of user record in %s: %m", fname);
403 }
404
405 h = hashmap_get(m->homes_by_name, name);
406 if (h) {
407 r = home_set_record(h, hr);
408 if (r < 0)
409 return log_error_errno(r, "Failed to update home record for %s: %m", name);
410
411 /* If we acquired a record now for a previously unallocated entry, then reset the state. This
412 * makes sure home_get_state() will check for the availability of the image file dynamically
162392b7 413 * in order to detect to distinguish HOME_INACTIVE and HOME_ABSENT. */
70a5db58
LP
414 if (h->state == HOME_UNFIXATED)
415 h->state = _HOME_STATE_INVALID;
416 } else {
417 r = home_new(m, hr, NULL, &h);
418 if (r < 0)
419 return log_error_errno(r, "Failed to allocate new home object: %m");
420
421 log_info("Added registered home for user %s.", hr->user_name);
422 }
423
424 /* Only entries we exclusively signed are writable to us, hence remember the result */
425 h->signed_locally = is_signed == USER_RECORD_SIGNED_EXCLUSIVE;
426
427 return 1;
20f4a308
LP
428
429unlink_this_file:
430 /* If this is an empty file, then let's just remove it. An empty file is not useful in any case, and
431 * apparently xfs likes to leave empty files around when not unmounted cleanly (see
432 * https://github.com/systemd/systemd/issues/15178 for example). Note that we don't delete non-empty
433 * files even if they are invalid, because that's just too risky, we might delete data the user still
434 * needs. But empty files are never useful, hence let's just remove them. */
435
436 if (unlinkat(dir_fd, fname, 0) < 0)
437 return log_error_errno(errno, "Failed to remove empty user record file %s: %m", fname);
438
005daeed 439 log_notice("Discovered empty user record file %s/%s, removed automatically.", home_record_dir(), fname);
20f4a308 440 return 0;
70a5db58
LP
441}
442
443static int manager_enumerate_records(Manager *m) {
444 _cleanup_closedir_ DIR *d = NULL;
445 struct dirent *de;
446
447 assert(m);
448
005daeed 449 d = opendir(home_record_dir());
70a5db58
LP
450 if (!d)
451 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
005daeed 452 "Failed to open %s: %m", home_record_dir());
70a5db58
LP
453
454 FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read record directory: %m")) {
455 _cleanup_free_ char *n = NULL;
456 const char *e;
457
458 if (!dirent_is_file(de))
459 continue;
460
461 e = endswith(de->d_name, ".identity");
462 if (!e)
463 continue;
464
465 n = strndup(de->d_name, e - de->d_name);
466 if (!n)
467 return log_oom();
468
469 if (!suitable_user_name(n))
470 continue;
471
472 (void) manager_add_home_by_record(m, n, dirfd(d), de->d_name);
473 }
474
475 return 0;
476}
477
478static int search_quota(uid_t uid, const char *exclude_quota_path) {
479 struct stat exclude_st = {};
480 dev_t previous_devno = 0;
481 const char *where;
482 int r;
483
484 /* Checks whether the specified UID owns any files on the files system, but ignore any file system
485 * backing the specified file. The file is used when operating on home directories, where it's OK if
486 * the UID of them already owns files. */
487
488 if (exclude_quota_path && stat(exclude_quota_path, &exclude_st) < 0) {
489 if (errno != ENOENT)
490 return log_warning_errno(errno, "Failed to stat %s, ignoring: %m", exclude_quota_path);
491 }
492
493 /* Check a few usual suspects where regular users might own files. Note that this is by no means
494 * comprehensive, but should cover most cases. Note that in an ideal world every user would be
495 * registered in NSS and avoid our own UID range, but for all other cases, it's a good idea to be
496 * paranoid and check quota if we can. */
2700fecd 497 FOREACH_STRING(where, get_home_root(), "/tmp/", "/var/", "/var/mail/", "/var/tmp/", "/var/spool/") {
70a5db58
LP
498 struct dqblk req;
499 struct stat st;
500
501 if (stat(where, &st) < 0) {
502 log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
503 "Failed to stat %s, ignoring: %m", where);
504 continue;
505 }
506
507 if (major(st.st_dev) == 0) {
508 log_debug("Directory %s is not on a real block device, not checking quota for UID use.", where);
509 continue;
510 }
511
512 if (st.st_dev == exclude_st.st_dev) { /* If an exclude path is specified, then ignore quota
513 * reported on the same block device as that path. */
514 log_debug("Directory %s is where the home directory is located, not checking quota for UID use.", where);
515 continue;
516 }
517
518 if (st.st_dev == previous_devno) { /* Does this directory have the same devno as the previous
519 * one we tested? If so, there's no point in testing this
520 * again. */
521 log_debug("Directory %s is on same device as previous tested directory, not checking quota for UID use a second time.", where);
522 continue;
523 }
524
525 previous_devno = st.st_dev;
526
527 r = quotactl_devno(QCMD_FIXED(Q_GETQUOTA, USRQUOTA), st.st_dev, uid, &req);
528 if (r < 0) {
529 if (ERRNO_IS_NOT_SUPPORTED(r))
530 log_debug_errno(r, "No UID quota support on %s, ignoring.", where);
5e5e11b8
LP
531 else if (ERRNO_IS_PRIVILEGE(r))
532 log_debug_errno(r, "UID quota support for %s prohibited, ignoring.", where);
70a5db58 533 else
1a53adb3 534 log_warning_errno(r, "Failed to query quota on %s, ignoring: %m", where);
70a5db58
LP
535
536 continue;
537 }
538
539 if ((FLAGS_SET(req.dqb_valid, QIF_SPACE) && req.dqb_curspace > 0) ||
540 (FLAGS_SET(req.dqb_valid, QIF_INODES) && req.dqb_curinodes > 0)) {
541 log_debug_errno(errno, "Quota reports UID " UID_FMT " occupies disk space on %s.", uid, where);
542 return 1;
543 }
544 }
545
546 return 0;
547}
548
549static int manager_acquire_uid(
550 Manager *m,
551 uid_t start_uid,
552 const char *user_name,
553 const char *exclude_quota_path,
554 uid_t *ret) {
555
556 static const uint8_t hash_key[] = {
557 0xa3, 0xb8, 0x82, 0x69, 0x9a, 0x71, 0xf7, 0xa9,
558 0xe0, 0x7c, 0xf6, 0xf1, 0x21, 0x69, 0xd2, 0x1e
559 };
560
561 enum {
562 PHASE_SUGGESTED,
563 PHASE_HASHED,
564 PHASE_RANDOM
565 } phase = PHASE_SUGGESTED;
566
567 unsigned n_tries = 100;
568 int r;
569
570 assert(m);
571 assert(ret);
572
573 for (;;) {
574 struct passwd *pw;
575 struct group *gr;
576 uid_t candidate;
577 Home *other;
578
579 if (--n_tries <= 0)
580 return -EBUSY;
581
582 switch (phase) {
583
584 case PHASE_SUGGESTED:
585 phase = PHASE_HASHED;
586
587 if (!uid_is_home(start_uid))
588 continue;
589
590 candidate = start_uid;
591 break;
592
593 case PHASE_HASHED:
594 phase = PHASE_RANDOM;
595
596 if (!user_name)
597 continue;
598
599 candidate = UID_CLAMP_INTO_HOME_RANGE(siphash24(user_name, strlen(user_name), hash_key));
600 break;
601
602 case PHASE_RANDOM:
603 random_bytes(&candidate, sizeof(candidate));
604 candidate = UID_CLAMP_INTO_HOME_RANGE(candidate);
605 break;
606
607 default:
04499a70 608 assert_not_reached();
70a5db58
LP
609 }
610
611 other = hashmap_get(m->homes_by_uid, UID_TO_PTR(candidate));
612 if (other) {
23d24b76
ZJS
613 log_debug("Candidate UID " UID_FMT " already used by another home directory (%s), let's try another.",
614 candidate, other->user_name);
70a5db58
LP
615 continue;
616 }
617
618 pw = getpwuid(candidate);
619 if (pw) {
23d24b76
ZJS
620 log_debug("Candidate UID " UID_FMT " already registered by another user in NSS (%s), let's try another.",
621 candidate, pw->pw_name);
70a5db58
LP
622 continue;
623 }
624
625 gr = getgrgid((gid_t) candidate);
626 if (gr) {
23d24b76
ZJS
627 log_debug("Candidate UID " UID_FMT " already registered by another group in NSS (%s), let's try another.",
628 candidate, gr->gr_name);
70a5db58
LP
629 continue;
630 }
631
632 r = search_ipc(candidate, (gid_t) candidate);
633 if (r < 0)
634 continue;
635 if (r > 0) {
23d24b76
ZJS
636 log_debug_errno(r, "Candidate UID " UID_FMT " already owns IPC objects, let's try another: %m",
637 candidate);
70a5db58
LP
638 continue;
639 }
640
641 r = search_quota(candidate, exclude_quota_path);
642 if (r != 0)
643 continue;
644
645 *ret = candidate;
646 return 0;
647 }
648}
649
650static int manager_add_home_by_image(
651 Manager *m,
652 const char *user_name,
653 const char *realm,
654 const char *image_path,
655 const char *sysfs,
656 UserStorage storage,
657 uid_t start_uid) {
658
659 _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
660 uid_t uid;
661 Home *h;
662 int r;
663
664 assert(m);
665
666 assert(m);
667 assert(user_name);
668 assert(image_path);
669 assert(storage >= 0);
670 assert(storage < _USER_STORAGE_MAX);
671
672 h = hashmap_get(m->homes_by_name, user_name);
673 if (h) {
674 bool same;
675
676 if (h->state != HOME_UNFIXATED) {
677 log_debug("Found an image for user %s which already has a record, skipping.", user_name);
678 return 0; /* ignore images that synthesize a user we already have a record for */
679 }
680
681 same = user_record_storage(h->record) == storage;
682 if (same) {
683 if (h->sysfs && sysfs)
684 same = path_equal(h->sysfs, sysfs);
685 else if (!!h->sysfs != !!sysfs)
686 same = false;
687 else {
688 const char *p;
689
690 p = user_record_image_path(h->record);
691 same = p && path_equal(p, image_path);
692 }
693 }
694
695 if (!same) {
80ace4f2 696 log_debug("Found multiple images for user '%s', ignoring image '%s'.", user_name, image_path);
70a5db58
LP
697 return 0;
698 }
699 } else {
700 /* Check NSS, in case there's another user or group by this name */
701 if (getpwnam(user_name) || getgrnam(user_name)) {
702 log_debug("Found an existing user or group by name '%s', ignoring image '%s'.", user_name, image_path);
703 return 0;
704 }
705 }
706
707 if (h && uid_is_valid(h->uid))
708 uid = h->uid;
709 else {
23d24b76
ZJS
710 r = manager_acquire_uid(m, start_uid, user_name,
711 IN_SET(storage, USER_SUBVOLUME, USER_DIRECTORY, USER_FSCRYPT) ? image_path : NULL,
712 &uid);
70a5db58
LP
713 if (r < 0)
714 return log_warning_errno(r, "Failed to acquire unused UID for %s: %m", user_name);
715 }
716
717 hr = user_record_new();
718 if (!hr)
719 return log_oom();
720
721 r = user_record_synthesize(hr, user_name, realm, image_path, storage, uid, (gid_t) uid);
722 if (r < 0)
723 return log_error_errno(r, "Failed to synthesize home record for %s (image %s): %m", user_name, image_path);
724
725 if (h) {
726 r = home_set_record(h, hr);
727 if (r < 0)
728 return log_error_errno(r, "Failed to update home record for %s: %m", user_name);
729 } else {
730 r = home_new(m, hr, sysfs, &h);
731 if (r < 0)
732 return log_error_errno(r, "Failed to allocate new home object: %m");
733
734 h->state = HOME_UNFIXATED;
735
736 log_info("Discovered new home for user %s through image %s.", user_name, image_path);
737 }
738
739 return 1;
740}
741
742int manager_augment_record_with_uid(
743 Manager *m,
744 UserRecord *hr) {
745
746 const char *exclude_quota_path = NULL;
747 uid_t start_uid = UID_INVALID, uid;
748 int r;
749
750 assert(m);
751 assert(hr);
752
753 if (uid_is_valid(hr->uid))
754 return 0;
755
756 if (IN_SET(hr->storage, USER_CLASSIC, USER_SUBVOLUME, USER_DIRECTORY, USER_FSCRYPT)) {
757 const char * ip;
758
759 ip = user_record_image_path(hr);
760 if (ip) {
761 struct stat st;
762
763 if (stat(ip, &st) < 0) {
764 if (errno != ENOENT)
765 log_warning_errno(errno, "Failed to stat(%s): %m", ip);
766 } else if (uid_is_home(st.st_uid)) {
767 start_uid = st.st_uid;
768 exclude_quota_path = ip;
769 }
770 }
771 }
772
773 r = manager_acquire_uid(m, start_uid, hr->user_name, exclude_quota_path, &uid);
774 if (r < 0)
775 return r;
776
777 log_debug("Acquired new UID " UID_FMT " for %s.", uid, hr->user_name);
778
779 r = user_record_add_binding(
780 hr,
781 _USER_STORAGE_INVALID,
782 NULL,
783 SD_ID128_NULL,
784 SD_ID128_NULL,
785 SD_ID128_NULL,
786 NULL,
787 NULL,
788 UINT64_MAX,
789 NULL,
790 NULL,
791 uid,
792 (gid_t) uid);
793 if (r < 0)
794 return r;
795
796 return 1;
797}
798
799static int manager_assess_image(
800 Manager *m,
801 int dir_fd,
802 const char *dir_path,
803 const char *dentry_name) {
804
805 char *luks_suffix, *directory_suffix;
806 _cleanup_free_ char *path = NULL;
807 struct stat st;
808 int r;
809
810 assert(m);
811 assert(dir_path);
812 assert(dentry_name);
813
814 luks_suffix = endswith(dentry_name, ".home");
815 if (luks_suffix)
816 directory_suffix = NULL;
817 else
818 directory_suffix = endswith(dentry_name, ".homedir");
819
820 /* Early filter out: by name */
821 if (!luks_suffix && !directory_suffix)
822 return 0;
823
824 path = path_join(dir_path, dentry_name);
825 if (!path)
826 return log_oom();
827
828 /* Follow symlinks here, to allow people to link in stuff to make them available locally. */
829 if (dir_fd >= 0)
830 r = fstatat(dir_fd, dentry_name, &st, 0);
831 else
832 r = stat(path, &st);
833 if (r < 0)
834 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
80ace4f2 835 "Failed to stat() directory entry '%s', ignoring: %m", dentry_name);
70a5db58
LP
836
837 if (S_ISREG(st.st_mode)) {
838 _cleanup_free_ char *n = NULL, *user_name = NULL, *realm = NULL;
839
840 if (!luks_suffix)
841 return 0;
842
843 n = strndup(dentry_name, luks_suffix - dentry_name);
844 if (!n)
845 return log_oom();
846
847 r = split_user_name_realm(n, &user_name, &realm);
848 if (r == -EINVAL) /* Not the right format: ignore */
849 return 0;
850 if (r < 0)
851 return log_error_errno(r, "Failed to split image name into user name/realm: %m");
852
853 return manager_add_home_by_image(m, user_name, realm, path, NULL, USER_LUKS, UID_INVALID);
854 }
855
856 if (S_ISDIR(st.st_mode)) {
857 _cleanup_free_ char *n = NULL, *user_name = NULL, *realm = NULL;
858 _cleanup_close_ int fd = -1;
859 UserStorage storage;
860
861 if (!directory_suffix)
862 return 0;
863
864 n = strndup(dentry_name, directory_suffix - dentry_name);
865 if (!n)
866 return log_oom();
867
868 r = split_user_name_realm(n, &user_name, &realm);
869 if (r == -EINVAL) /* Not the right format: ignore */
870 return 0;
871 if (r < 0)
872 return log_error_errno(r, "Failed to split image name into user name/realm: %m");
873
874 if (dir_fd >= 0)
875 fd = openat(dir_fd, dentry_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
876 else
877 fd = open(path, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
878 if (fd < 0)
879 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
880 "Failed to open directory '%s', ignoring: %m", path);
881
882 if (fstat(fd, &st) < 0)
883 return log_warning_errno(errno, "Failed to fstat() %s, ignoring: %m", path);
884
885 assert(S_ISDIR(st.st_mode)); /* Must hold, we used O_DIRECTORY above */
886
887 r = btrfs_is_subvol_fd(fd);
888 if (r < 0)
889 return log_warning_errno(errno, "Failed to determine whether %s is a btrfs subvolume: %m", path);
890 if (r > 0)
891 storage = USER_SUBVOLUME;
892 else {
893 struct fscrypt_policy policy;
894
895 if (ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, &policy) < 0) {
896
897 if (errno == ENODATA)
898 log_debug_errno(errno, "Determined %s is not fscrypt encrypted.", path);
899 else if (ERRNO_IS_NOT_SUPPORTED(errno))
80ace4f2 900 log_debug_errno(errno, "Determined %s is not fscrypt encrypted because kernel or file system doesn't support it.", path);
70a5db58
LP
901 else
902 log_debug_errno(errno, "FS_IOC_GET_ENCRYPTION_POLICY failed with unexpected error code on %s, ignoring: %m", path);
903
904 storage = USER_DIRECTORY;
905 } else
906 storage = USER_FSCRYPT;
907 }
908
909 return manager_add_home_by_image(m, user_name, realm, path, NULL, storage, st.st_uid);
910 }
911
912 return 0;
913}
914
915int manager_enumerate_images(Manager *m) {
916 _cleanup_closedir_ DIR *d = NULL;
917 struct dirent *de;
918
919 assert(m);
920
921 if (!m->scan_slash_home)
922 return 0;
923
2700fecd 924 d = opendir(get_home_root());
70a5db58
LP
925 if (!d)
926 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
2700fecd 927 "Failed to open %s: %m", get_home_root());
70a5db58 928
2700fecd
LP
929 FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read %s directory: %m", get_home_root()))
930 (void) manager_assess_image(m, dirfd(d), get_home_root(), de->d_name);
70a5db58
LP
931
932 return 0;
933}
934
935static int manager_connect_bus(Manager *m) {
cc9886bc 936 const char *suffix, *busname;
70a5db58
LP
937 int r;
938
939 assert(m);
940 assert(!m->bus);
941
942 r = sd_bus_default_system(&m->bus);
943 if (r < 0)
944 return log_error_errno(r, "Failed to connect to system bus: %m");
945
cfd508a9 946 r = bus_add_implementation(m->bus, &manager_object, m);
ac9f55ed
LP
947 if (r < 0)
948 return r;
949
cc9886bc
LP
950 suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
951 if (suffix)
952 busname = strjoina("org.freedesktop.home1.", suffix);
953 else
954 busname = "org.freedesktop.home1";
955
956 r = sd_bus_request_name_async(m->bus, NULL, busname, 0, NULL, NULL);
70a5db58
LP
957 if (r < 0)
958 return log_error_errno(r, "Failed to request name: %m");
959
960 r = sd_bus_attach_event(m->bus, m->event, 0);
961 if (r < 0)
962 return log_error_errno(r, "Failed to attach bus to event loop: %m");
963
964 (void) sd_bus_set_exit_on_disconnect(m->bus, true);
965
966 return 0;
967}
968
969static int manager_bind_varlink(Manager *m) {
cc9886bc 970 const char *suffix, *socket_path;
70a5db58
LP
971 int r;
972
973 assert(m);
974 assert(!m->varlink_server);
975
9807fdc1 976 r = varlink_server_new(&m->varlink_server, VARLINK_SERVER_ACCOUNT_UID|VARLINK_SERVER_INHERIT_USERDATA);
70a5db58
LP
977 if (r < 0)
978 return log_error_errno(r, "Failed to allocate varlink server object: %m");
979
980 varlink_server_set_userdata(m->varlink_server, m);
981
982 r = varlink_server_bind_method_many(
983 m->varlink_server,
984 "io.systemd.UserDatabase.GetUserRecord", vl_method_get_user_record,
985 "io.systemd.UserDatabase.GetGroupRecord", vl_method_get_group_record,
986 "io.systemd.UserDatabase.GetMemberships", vl_method_get_memberships);
987 if (r < 0)
988 return log_error_errno(r, "Failed to register varlink methods: %m");
989
990 (void) mkdir_p("/run/systemd/userdb", 0755);
991
cc9886bc
LP
992 /* To make things easier to debug, when working from a homed managed home directory, let's optionally
993 * use a different varlink socket name */
994 suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
995 if (suffix)
996 socket_path = strjoina("/run/systemd/userdb/io.systemd.Home.", suffix);
997 else
998 socket_path = "/run/systemd/userdb/io.systemd.Home";
999
1000 r = varlink_server_listen_address(m->varlink_server, socket_path, 0666);
70a5db58
LP
1001 if (r < 0)
1002 return log_error_errno(r, "Failed to bind to varlink socket: %m");
1003
1004 r = varlink_server_attach_event(m->varlink_server, m->event, SD_EVENT_PRIORITY_NORMAL);
1005 if (r < 0)
1006 return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
1007
cc9886bc
LP
1008 assert(!m->userdb_service);
1009 m->userdb_service = strdup(basename(socket_path));
1010 if (!m->userdb_service)
1011 return log_oom();
1012
1013 /* Avoid recursion */
1014 if (setenv("SYSTEMD_BYPASS_USERDB", m->userdb_service, 1) < 0)
1015 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to set $SYSTEMD_BYPASS_USERDB: %m");
1016
70a5db58
LP
1017 return 0;
1018}
1019
2aaf565a
LP
1020static ssize_t read_datagram(
1021 int fd,
1022 struct ucred *ret_sender,
1023 void **ret,
1024 int *ret_passed_fd) {
1025
1026 CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int))) control;
70a5db58 1027 _cleanup_free_ void *buffer = NULL;
2aaf565a
LP
1028 _cleanup_close_ int passed_fd = -1;
1029 struct ucred *sender = NULL;
1030 struct cmsghdr *cmsg;
1031 struct msghdr mh;
1032 struct iovec iov;
70a5db58
LP
1033 ssize_t n, m;
1034
1035 assert(fd >= 0);
1036 assert(ret_sender);
1037 assert(ret);
2aaf565a 1038 assert(ret_passed_fd);
70a5db58
LP
1039
1040 n = next_datagram_size_fd(fd);
1041 if (n < 0)
1042 return n;
1043
1044 buffer = malloc(n + 2);
1045 if (!buffer)
1046 return -ENOMEM;
1047
2aaf565a
LP
1048 /* Pass one extra byte, as a size check */
1049 iov = IOVEC_MAKE(buffer, n + 1);
70a5db58 1050
2aaf565a
LP
1051 mh = (struct msghdr) {
1052 .msg_iov = &iov,
1053 .msg_iovlen = 1,
1054 .msg_control = &control,
1055 .msg_controllen = sizeof(control),
1056 };
70a5db58 1057
2aaf565a
LP
1058 m = recvmsg_safe(fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
1059 if (m < 0)
1060 return m;
70a5db58 1061
2aaf565a
LP
1062 /* Ensure the size matches what we determined before */
1063 if (m != n) {
70a5db58 1064 cmsg_close_all(&mh);
2aaf565a
LP
1065 return -EMSGSIZE;
1066 }
70a5db58 1067
2aaf565a
LP
1068 CMSG_FOREACH(cmsg, &mh) {
1069 if (cmsg->cmsg_level == SOL_SOCKET &&
1070 cmsg->cmsg_type == SCM_CREDENTIALS &&
1071 cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
1072 assert(!sender);
1073 sender = (struct ucred*) CMSG_DATA(cmsg);
1074 }
70a5db58 1075
2aaf565a
LP
1076 if (cmsg->cmsg_level == SOL_SOCKET &&
1077 cmsg->cmsg_type == SCM_RIGHTS) {
70a5db58 1078
2aaf565a
LP
1079 if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
1080 cmsg_close_all(&mh);
1081 return -EMSGSIZE;
70a5db58
LP
1082 }
1083
2aaf565a
LP
1084 assert(passed_fd < 0);
1085 passed_fd = *(int*) CMSG_DATA(cmsg);
1086 }
70a5db58
LP
1087 }
1088
2aaf565a
LP
1089 if (sender)
1090 *ret_sender = *sender;
1091 else
1092 *ret_sender = (struct ucred) UCRED_INVALID;
1093
1094 *ret_passed_fd = TAKE_FD(passed_fd);
1095
70a5db58
LP
1096 /* For safety reasons: let's always NUL terminate. */
1097 ((char*) buffer)[n] = 0;
1098 *ret = TAKE_PTR(buffer);
1099
1100 return 0;
1101}
1102
1103static int on_notify_socket(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
1104 _cleanup_strv_free_ char **l = NULL;
1105 _cleanup_free_ void *datagram = NULL;
2aaf565a
LP
1106 _cleanup_close_ int passed_fd = -1;
1107 struct ucred sender = UCRED_INVALID;
70a5db58
LP
1108 Manager *m = userdata;
1109 ssize_t n;
1110 Home *h;
1111
1112 assert(s);
1113 assert(m);
1114
2aaf565a 1115 n = read_datagram(fd, &sender, &datagram, &passed_fd);
70a5db58
LP
1116 if (IN_SET(n, -EAGAIN, -EINTR))
1117 return 0;
1118 if (n < 0)
1119 return log_error_errno(n, "Failed to read notify datagram: %m");
1120
1121 if (sender.pid <= 0) {
1122 log_warning("Received notify datagram without valid sender PID, ignoring.");
1123 return 0;
1124 }
1125
1126 h = hashmap_get(m->homes_by_worker_pid, PID_TO_PTR(sender.pid));
1127 if (!h) {
162392b7 1128 log_warning("Received notify datagram of unknown process, ignoring.");
70a5db58
LP
1129 return 0;
1130 }
1131
1132 l = strv_split(datagram, "\n");
1133 if (!l)
1134 return log_oom();
1135
2aaf565a 1136 home_process_notify(h, l, TAKE_FD(passed_fd));
70a5db58
LP
1137 return 0;
1138}
1139
1140static int manager_listen_notify(Manager *m) {
1141 _cleanup_close_ int fd = -1;
425d925f
ZJS
1142 union sockaddr_union sa = {
1143 .un.sun_family = AF_UNIX,
1144 .un.sun_path = "/run/systemd/home/notify",
1145 };
cc9886bc 1146 const char *suffix;
70a5db58
LP
1147 int r;
1148
1149 assert(m);
1150 assert(!m->notify_socket_event_source);
1151
cc9886bc
LP
1152 suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
1153 if (suffix) {
1154 const char *unix_path;
1155
1156 unix_path = strjoina("/run/systemd/home/notify.", suffix);
1157 r = sockaddr_un_set_path(&sa.un, unix_path);
1158 if (r < 0)
1159 return log_error_errno(r, "Socket path %s does not fit in sockaddr_un: %m", unix_path);
1160 }
1161
70a5db58
LP
1162 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
1163 if (fd < 0)
1164 return log_error_errno(errno, "Failed to create listening socket: %m");
1165
70a5db58
LP
1166 (void) mkdir_parents(sa.un.sun_path, 0755);
1167 (void) sockaddr_un_unlink(&sa.un);
1168
1169 if (bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
1170 return log_error_errno(errno, "Failed to bind to socket: %m");
1171
1172 r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true);
1173 if (r < 0)
1174 return r;
1175
1176 r = sd_event_add_io(m->event, &m->notify_socket_event_source, fd, EPOLLIN, on_notify_socket, m);
1177 if (r < 0)
1178 return log_error_errno(r, "Failed to allocate event source for notify socket: %m");
1179
1180 (void) sd_event_source_set_description(m->notify_socket_event_source, "notify-socket");
1181
1182 /* Make sure we process sd_notify() before SIGCHLD for any worker, so that we always know the error
1183 * number of a client before it exits. */
1184 r = sd_event_source_set_priority(m->notify_socket_event_source, SD_EVENT_PRIORITY_NORMAL - 5);
1185 if (r < 0)
1186 return log_error_errno(r, "Failed to alter priority of NOTIFY_SOCKET event source: %m");
1187
1188 r = sd_event_source_set_io_fd_own(m->notify_socket_event_source, true);
1189 if (r < 0)
1190 return log_error_errno(r, "Failed to pass ownership of notify socket: %m");
1191
1192 return TAKE_FD(fd);
1193}
1194
1195static int manager_add_device(Manager *m, sd_device *d) {
1196 _cleanup_free_ char *user_name = NULL, *realm = NULL, *node = NULL;
1197 const char *tabletype, *parttype, *partname, *partuuid, *sysfs;
1198 sd_id128_t id;
1199 int r;
1200
1201 assert(m);
1202 assert(d);
1203
1204 r = sd_device_get_syspath(d, &sysfs);
1205 if (r < 0)
1206 return log_error_errno(r, "Failed to acquire sysfs path of device: %m");
1207
1208 r = sd_device_get_property_value(d, "ID_PART_TABLE_TYPE", &tabletype);
1209 if (r == -ENOENT)
1210 return 0;
1211 if (r < 0)
1212 return log_error_errno(r, "Failed to acquire ID_PART_TABLE_TYPE device property, ignoring: %m");
1213
1214 if (!streq(tabletype, "gpt")) {
1215 log_debug("Found partition (%s) on non-GPT table, ignoring.", sysfs);
1216 return 0;
1217 }
1218
1219 r = sd_device_get_property_value(d, "ID_PART_ENTRY_TYPE", &parttype);
1220 if (r == -ENOENT)
1221 return 0;
1222 if (r < 0)
1223 return log_error_errno(r, "Failed to acquire ID_PART_ENTRY_TYPE device property, ignoring: %m");
1224 r = sd_id128_from_string(parttype, &id);
1225 if (r < 0)
1226 return log_debug_errno(r, "Failed to parse ID_PART_ENTRY_TYPE field '%s', ignoring: %m", parttype);
1227 if (!sd_id128_equal(id, GPT_USER_HOME)) {
1228 log_debug("Found partition (%s) we don't care about, ignoring.", sysfs);
1229 return 0;
1230 }
1231
1232 r = sd_device_get_property_value(d, "ID_PART_ENTRY_NAME", &partname);
1233 if (r < 0)
1234 return log_warning_errno(r, "Failed to acquire ID_PART_ENTRY_NAME device property, ignoring: %m");
1235
1236 r = split_user_name_realm(partname, &user_name, &realm);
1237 if (r == -EINVAL)
1238 return log_warning_errno(r, "Found partition with correct partition type but a non-parsable partition name '%s', ignoring.", partname);
1239 if (r < 0)
1240 return log_error_errno(r, "Failed to validate partition name '%s': %m", partname);
1241
1242 r = sd_device_get_property_value(d, "ID_FS_UUID", &partuuid);
1243 if (r < 0)
1244 return log_warning_errno(r, "Failed to acquire ID_FS_UUID device property, ignoring: %m");
1245
1246 r = sd_id128_from_string(partuuid, &id);
1247 if (r < 0)
1248 return log_warning_errno(r, "Failed to parse ID_FS_UUID field '%s', ignoring: %m", partuuid);
1249
1250 if (asprintf(&node, "/dev/disk/by-uuid/" SD_ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(id)) < 0)
1251 return log_oom();
1252
1253 return manager_add_home_by_image(m, user_name, realm, node, sysfs, USER_LUKS, UID_INVALID);
1254}
1255
1256static int manager_on_device(sd_device_monitor *monitor, sd_device *d, void *userdata) {
1257 Manager *m = userdata;
1258 int r;
1259
1260 assert(m);
1261 assert(d);
1262
a1130022 1263 if (device_for_action(d, SD_DEVICE_REMOVE)) {
70a5db58
LP
1264 const char *sysfs;
1265 Home *h;
1266
1267 r = sd_device_get_syspath(d, &sysfs);
1268 if (r < 0) {
1269 log_warning_errno(r, "Failed to acquire sysfs path from device: %m");
1270 return 0;
1271 }
1272
1273 log_info("block device %s has been removed.", sysfs);
1274
1275 /* Let's see if we previously synthesized a home record from this device, if so, let's just
1276 * revalidate that. Otherwise let's revalidate them all, but asynchronously. */
1277 h = hashmap_get(m->homes_by_sysfs, sysfs);
1278 if (h)
1279 manager_revalidate_image(m, h);
1280 else
1281 manager_enqueue_gc(m, NULL);
1282 } else
1283 (void) manager_add_device(m, d);
1284
1285 (void) bus_manager_emit_auto_login_changed(m);
1286 return 0;
1287}
1288
1289static int manager_watch_devices(Manager *m) {
1290 int r;
1291
1292 assert(m);
1293 assert(!m->device_monitor);
1294
1295 r = sd_device_monitor_new(&m->device_monitor);
1296 if (r < 0)
1297 return log_error_errno(r, "Failed to allocate device monitor: %m");
1298
1299 r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "block", NULL);
1300 if (r < 0)
1301 return log_error_errno(r, "Failed to configure device monitor match: %m");
1302
1303 r = sd_device_monitor_attach_event(m->device_monitor, m->event);
1304 if (r < 0)
1305 return log_error_errno(r, "Failed to attach device monitor to event loop: %m");
1306
1307 r = sd_device_monitor_start(m->device_monitor, manager_on_device, m);
1308 if (r < 0)
1309 return log_error_errno(r, "Failed to start device monitor: %m");
1310
1311 return 0;
1312}
1313
1314static int manager_enumerate_devices(Manager *m) {
1315 _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
1316 sd_device *d;
1317 int r;
1318
1319 assert(m);
1320
1321 r = sd_device_enumerator_new(&e);
1322 if (r < 0)
1323 return r;
1324
1325 r = sd_device_enumerator_add_match_subsystem(e, "block", true);
1326 if (r < 0)
1327 return r;
1328
1329 FOREACH_DEVICE(e, d)
1330 (void) manager_add_device(m, d);
1331
1332 return 0;
1333}
1334
1335static int manager_load_key_pair(Manager *m) {
1336 _cleanup_(fclosep) FILE *f = NULL;
1337 struct stat st;
1338 int r;
1339
1340 assert(m);
1341
1342 if (m->private_key) {
1343 EVP_PKEY_free(m->private_key);
1344 m->private_key = NULL;
1345 }
1346
2708160c 1347 r = search_and_fopen_nulstr("local.private", "re", NULL, KEY_PATHS_NULSTR, &f, NULL);
70a5db58
LP
1348 if (r == -ENOENT)
1349 return 0;
1350 if (r < 0)
1351 return log_error_errno(r, "Failed to read private key file: %m");
1352
1353 if (fstat(fileno(f), &st) < 0)
1354 return log_error_errno(errno, "Failed to stat private key file: %m");
1355
1356 r = stat_verify_regular(&st);
1357 if (r < 0)
1358 return log_error_errno(r, "Private key file is not regular: %m");
1359
1360 if (st.st_uid != 0 || (st.st_mode & 0077) != 0)
1361 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Private key file is readable by more than the root user");
1362
1363 m->private_key = PEM_read_PrivateKey(f, NULL, NULL, NULL);
1364 if (!m->private_key)
1365 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to load private key pair");
1366
1367 log_info("Successfully loaded private key pair.");
1368
1369 return 1;
1370}
1371
fd421c4a 1372DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY_CTX*, EVP_PKEY_CTX_free, NULL);
70a5db58
LP
1373
1374static int manager_generate_key_pair(Manager *m) {
1375 _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = NULL;
1376 _cleanup_(unlink_and_freep) char *temp_public = NULL, *temp_private = NULL;
1377 _cleanup_fclose_ FILE *fpublic = NULL, *fprivate = NULL;
1378 int r;
1379
1380 if (m->private_key) {
1381 EVP_PKEY_free(m->private_key);
1382 m->private_key = NULL;
1383 }
1384
1385 ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL);
1386 if (!ctx)
1387 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to allocate Ed25519 key generation context.");
1388
1389 if (EVP_PKEY_keygen_init(ctx) <= 0)
1390 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize Ed25519 key generation context.");
1391
1392 log_info("Generating key pair for signing local user identity records.");
1393
1394 if (EVP_PKEY_keygen(ctx, &m->private_key) <= 0)
1395 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to generate Ed25519 key pair");
1396
1397 log_info("Successfully created Ed25519 key pair.");
1398
1399 (void) mkdir_p("/var/lib/systemd/home", 0755);
1400
1401 /* Write out public key (note that we only do that as a help to the user, we don't make use of this ever */
1402 r = fopen_temporary("/var/lib/systemd/home/local.public", &fpublic, &temp_public);
1403 if (r < 0)
80ace4f2 1404 return log_error_errno(errno, "Failed to open key file for writing: %m");
70a5db58
LP
1405
1406 if (PEM_write_PUBKEY(fpublic, m->private_key) <= 0)
1407 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write public key.");
1408
fa3709c5 1409 r = fflush_sync_and_check(fpublic);
70a5db58
LP
1410 if (r < 0)
1411 return log_error_errno(r, "Failed to write private key: %m");
1412
1413 fpublic = safe_fclose(fpublic);
1414
1415 /* Write out the private key (this actually writes out both private and public, OpenSSL is confusing) */
1416 r = fopen_temporary("/var/lib/systemd/home/local.private", &fprivate, &temp_private);
1417 if (r < 0)
80ace4f2 1418 return log_error_errno(errno, "Failed to open key file for writing: %m");
70a5db58
LP
1419
1420 if (PEM_write_PrivateKey(fprivate, m->private_key, NULL, NULL, 0, NULL, 0) <= 0)
1421 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write private key pair.");
1422
fa3709c5 1423 r = fflush_sync_and_check(fprivate);
70a5db58
LP
1424 if (r < 0)
1425 return log_error_errno(r, "Failed to write private key: %m");
1426
1427 fprivate = safe_fclose(fprivate);
1428
1429 /* Both are written now, move them into place */
1430
1431 if (rename(temp_public, "/var/lib/systemd/home/local.public") < 0)
1432 return log_error_errno(errno, "Failed to move public key file into place: %m");
1433 temp_public = mfree(temp_public);
1434
1435 if (rename(temp_private, "/var/lib/systemd/home/local.private") < 0) {
1436 (void) unlink_noerrno("/var/lib/systemd/home/local.public"); /* try to remove the file we already created */
e8dd54ab 1437 return log_error_errno(errno, "Failed to move private key file into place: %m");
70a5db58
LP
1438 }
1439 temp_private = mfree(temp_private);
1440
fa3709c5
LP
1441 r = fsync_path_at(AT_FDCWD, "/var/lib/systemd/home/");
1442 if (r < 0)
1443 log_warning_errno(r, "Failed to sync /var/lib/systemd/home/, ignoring: %m");
1444
70a5db58
LP
1445 return 1;
1446}
1447
1448int manager_acquire_key_pair(Manager *m) {
1449 int r;
1450
1451 assert(m);
1452
1453 /* Already there? */
1454 if (m->private_key)
1455 return 1;
1456
1457 /* First try to load key off disk */
1458 r = manager_load_key_pair(m);
1459 if (r != 0)
1460 return r;
1461
1462 /* Didn't work, generate a new one */
1463 return manager_generate_key_pair(m);
1464}
1465
1466int manager_sign_user_record(Manager *m, UserRecord *u, UserRecord **ret, sd_bus_error *error) {
1467 int r;
1468
1469 assert(m);
1470 assert(u);
1471 assert(ret);
1472
1473 r = manager_acquire_key_pair(m);
1474 if (r < 0)
1475 return r;
1476 if (r == 0)
1b09b81c 1477 return sd_bus_error_set(error, BUS_ERROR_NO_PRIVATE_KEY, "Can't sign without local key.");
70a5db58
LP
1478
1479 return user_record_sign(u, m->private_key, ret);
1480}
1481
1482DEFINE_PRIVATE_HASH_OPS_FULL(public_key_hash_ops, char, string_hash_func, string_compare_func, free, EVP_PKEY, EVP_PKEY_free);
fd421c4a 1483DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EVP_PKEY*, EVP_PKEY_free, NULL);
70a5db58
LP
1484
1485static int manager_load_public_key_one(Manager *m, const char *path) {
1486 _cleanup_(EVP_PKEY_freep) EVP_PKEY *pkey = NULL;
1487 _cleanup_fclose_ FILE *f = NULL;
1488 _cleanup_free_ char *fn = NULL;
1489 struct stat st;
1490 int r;
1491
1492 assert(m);
1493
1494 if (streq(basename(path), "local.public")) /* we already loaded the private key, which includes the public one */
1495 return 0;
1496
1497 f = fopen(path, "re");
1498 if (!f) {
1499 if (errno == ENOENT)
1500 return 0;
1501
1502 return log_error_errno(errno, "Failed to open public key %s: %m", path);
1503 }
1504
1505 if (fstat(fileno(f), &st) < 0)
1506 return log_error_errno(errno, "Failed to stat public key %s: %m", path);
1507
1508 r = stat_verify_regular(&st);
1509 if (r < 0)
1510 return log_error_errno(r, "Public key file %s is not a regular file: %m", path);
1511
1512 if (st.st_uid != 0 || (st.st_mode & 0022) != 0)
1513 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Public key file %s is writable by more than the root user, refusing.", path);
1514
1515 r = hashmap_ensure_allocated(&m->public_keys, &public_key_hash_ops);
1516 if (r < 0)
1517 return log_oom();
1518
1519 pkey = PEM_read_PUBKEY(f, &pkey, NULL, NULL);
1520 if (!pkey)
1521 return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key file %s.", path);
1522
1523 fn = strdup(basename(path));
1524 if (!fn)
1525 return log_oom();
1526
1527 r = hashmap_put(m->public_keys, fn, pkey);
1528 if (r < 0)
1529 return log_error_errno(r, "Failed to add public key to set: %m");
1530
1531 TAKE_PTR(fn);
1532 TAKE_PTR(pkey);
1533
1534 return 0;
1535}
1536
1537static int manager_load_public_keys(Manager *m) {
1538 _cleanup_strv_free_ char **files = NULL;
1539 char **i;
1540 int r;
1541
1542 assert(m);
1543
1544 m->public_keys = hashmap_free(m->public_keys);
1545
1546 r = conf_files_list_nulstr(
1547 &files,
1548 ".public",
1549 NULL,
1550 CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED,
1551 KEY_PATHS_NULSTR);
1552 if (r < 0)
1553 return log_error_errno(r, "Failed to assemble list of public key directories: %m");
1554
1555 STRV_FOREACH(i, files)
1556 (void) manager_load_public_key_one(m, *i);
1557
1558 return 0;
1559}
1560
1561int manager_startup(Manager *m) {
1562 int r;
1563
1564 assert(m);
1565
1566 r = manager_listen_notify(m);
1567 if (r < 0)
1568 return r;
1569
1570 r = manager_connect_bus(m);
1571 if (r < 0)
1572 return r;
1573
1574 r = manager_bind_varlink(m);
1575 if (r < 0)
1576 return r;
1577
1578 r = manager_load_key_pair(m); /* only try to load it, don't generate any */
1579 if (r < 0)
1580 return r;
1581
1582 r = manager_load_public_keys(m);
1583 if (r < 0)
1584 return r;
1585
1586 manager_watch_home(m);
1587 (void) manager_watch_devices(m);
1588
1589 (void) manager_enumerate_records(m);
1590 (void) manager_enumerate_images(m);
1591 (void) manager_enumerate_devices(m);
1592
1593 /* Let's clean up home directories whose devices got removed while we were not running */
1594 (void) manager_enqueue_gc(m, NULL);
1595
1596 return 0;
1597}
1598
1599void manager_revalidate_image(Manager *m, Home *h) {
1600 int r;
1601
1602 assert(m);
1603 assert(h);
1604
1605 /* Frees an automatically discovered image, if it's synthetic and its image disappeared. Unmounts any
1606 * image if it's mounted but it's image vanished. */
1607
1608 if (h->current_operation || !ordered_set_isempty(h->pending_operations))
1609 return;
1610
1611 if (h->state == HOME_UNFIXATED) {
1612 r = user_record_test_image_path(h->record);
1613 if (r < 0)
1614 log_warning_errno(r, "Can't determine if image of %s exists, freeing unfixated user: %m", h->user_name);
1615 else if (r == USER_TEST_ABSENT)
1616 log_info("Image for %s disappeared, freeing unfixated user.", h->user_name);
1617 else
1618 return;
1619
1620 home_free(h);
1621
1622 } else if (h->state < 0) {
1623
1624 r = user_record_test_home_directory(h->record);
1625 if (r < 0) {
1626 log_warning_errno(r, "Unable to determine state of home directory, ignoring: %m");
1627 return;
1628 }
1629
1630 if (r == USER_TEST_MOUNTED) {
1631 r = user_record_test_image_path(h->record);
1632 if (r < 0) {
1633 log_warning_errno(r, "Unable to determine state of image path, ignoring: %m");
1634 return;
1635 }
1636
1637 if (r == USER_TEST_ABSENT) {
1638 _cleanup_(operation_unrefp) Operation *o = NULL;
1639
1640 log_notice("Backing image disappeared while home directory %s was mounted, unmounting it forcibly.", h->user_name);
1641 /* Wowza, the thing is mounted, but the device is gone? Act on it. */
1642
1643 r = home_killall(h);
1644 if (r < 0)
1645 log_warning_errno(r, "Failed to kill processes of user %s, ignoring: %m", h->user_name);
1646
1647 /* We enqueue the operation here, after all the home directory might
1648 * currently already run some operation, and we can deactivate it only after
1649 * that's complete. */
1650 o = operation_new(OPERATION_DEACTIVATE_FORCE, NULL);
1651 if (!o) {
1652 log_oom();
1653 return;
1654 }
1655
1656 r = home_schedule_operation(h, o, NULL);
1657 if (r < 0)
1658 log_warning_errno(r, "Failed to enqueue forced home directory %s deactivation, ignoring: %m", h->user_name);
1659 }
1660 }
1661 }
1662}
1663
1664int manager_gc_images(Manager *m) {
1665 Home *h;
1666
1667 assert_se(m);
1668
1669 if (m->gc_focus) {
1670 /* Focus on a specific home */
1671
1672 h = TAKE_PTR(m->gc_focus);
1673 manager_revalidate_image(m, h);
1674 } else {
1675 /* Gc all */
70a5db58 1676
90e74a66 1677 HASHMAP_FOREACH(h, m->homes_by_name)
70a5db58
LP
1678 manager_revalidate_image(m, h);
1679 }
1680
1681 return 0;
1682}
1683
1684static int on_deferred_rescan(sd_event_source *s, void *userdata) {
1685 Manager *m = userdata;
1686
1687 assert(m);
1688
cf536638 1689 m->deferred_rescan_event_source = sd_event_source_disable_unref(m->deferred_rescan_event_source);
70a5db58
LP
1690
1691 manager_enumerate_devices(m);
1692 manager_enumerate_images(m);
1693 return 0;
1694}
1695
1696int manager_enqueue_rescan(Manager *m) {
1697 int r;
1698
1699 assert(m);
1700
1701 if (m->deferred_rescan_event_source)
1702 return 0;
1703
1704 if (!m->event)
1705 return 0;
1706
1707 if (IN_SET(sd_event_get_state(m->event), SD_EVENT_FINISHED, SD_EVENT_EXITING))
1708 return 0;
1709
1710 r = sd_event_add_defer(m->event, &m->deferred_rescan_event_source, on_deferred_rescan, m);
1711 if (r < 0)
1712 return log_error_errno(r, "Failed to allocate rescan event source: %m");
1713
1714 r = sd_event_source_set_priority(m->deferred_rescan_event_source, SD_EVENT_PRIORITY_IDLE+1);
1715 if (r < 0)
1716 log_warning_errno(r, "Failed to tweak priority of event source, ignoring: %m");
1717
1718 (void) sd_event_source_set_description(m->deferred_rescan_event_source, "deferred-rescan");
1719 return 1;
1720}
1721
1722static int on_deferred_gc(sd_event_source *s, void *userdata) {
1723 Manager *m = userdata;
1724
1725 assert(m);
1726
cf536638 1727 m->deferred_gc_event_source = sd_event_source_disable_unref(m->deferred_gc_event_source);
70a5db58
LP
1728
1729 manager_gc_images(m);
1730 return 0;
1731}
1732
1733int manager_enqueue_gc(Manager *m, Home *focus) {
1734 int r;
1735
1736 assert(m);
1737
1738 /* This enqueues a request to GC dead homes. It may be called with focus=NULL in which case all homes
1739 * will be scanned, or with the parameter set, in which case only that home is checked. */
1740
1741 if (!m->event)
1742 return 0;
1743
1744 if (IN_SET(sd_event_get_state(m->event), SD_EVENT_FINISHED, SD_EVENT_EXITING))
1745 return 0;
1746
1747 /* If a focus home is specified, then remember to focus just on this home. Otherwise invalidate any
1748 * focus that might be set to look at all homes. */
1749
1750 if (m->deferred_gc_event_source) {
1751 if (m->gc_focus != focus) /* not the same focus, then look at everything */
1752 m->gc_focus = NULL;
1753
1754 return 0;
1755 } else
162392b7 1756 m->gc_focus = focus; /* start focused */
70a5db58
LP
1757
1758 r = sd_event_add_defer(m->event, &m->deferred_gc_event_source, on_deferred_gc, m);
1759 if (r < 0)
80ace4f2 1760 return log_error_errno(r, "Failed to allocate GC event source: %m");
70a5db58
LP
1761
1762 r = sd_event_source_set_priority(m->deferred_gc_event_source, SD_EVENT_PRIORITY_IDLE);
1763 if (r < 0)
1764 log_warning_errno(r, "Failed to tweak priority of event source, ignoring: %m");
1765
1766 (void) sd_event_source_set_description(m->deferred_gc_event_source, "deferred-gc");
1767 return 1;
1768}