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