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