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