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