]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/home/homed-home.c
Merge pull request #15442 from poettering/fido2
[thirdparty/systemd.git] / src / home / homed-home.c
CommitLineData
70a5db58
LP
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#if HAVE_LINUX_MEMFD_H
4#include <linux/memfd.h>
5#endif
6
7#include <sys/mman.h>
8#include <sys/quota.h>
9#include <sys/vfs.h>
10
11#include "blockdev-util.h"
12#include "btrfs-util.h"
13#include "bus-common-errors.h"
14#include "env-util.h"
15#include "errno-list.h"
16#include "errno-util.h"
17#include "fd-util.h"
18#include "fileio.h"
19#include "home-util.h"
20#include "homed-home-bus.h"
21#include "homed-home.h"
22#include "missing_syscall.h"
23#include "mkdir.h"
24#include "path-util.h"
25#include "process-util.h"
26#include "pwquality-util.h"
27#include "quota-util.h"
28#include "resize-fs.h"
29#include "set.h"
30#include "signal-util.h"
31#include "stat-util.h"
32#include "string-table.h"
33#include "strv.h"
34#include "user-record-sign.h"
35#include "user-record-util.h"
36#include "user-record.h"
37#include "user-util.h"
38
39#define HOME_USERS_MAX 500
40#define PENDING_OPERATIONS_MAX 100
41
42assert_cc(HOME_UID_MIN <= HOME_UID_MAX);
43assert_cc(HOME_USERS_MAX <= (HOME_UID_MAX - HOME_UID_MIN + 1));
44
45static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord *secret);
46
47DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(operation_hash_ops, void, trivial_hash_func, trivial_compare_func, Operation, operation_unref);
48
49static int suitable_home_record(UserRecord *hr) {
50 int r;
51
52 assert(hr);
53
54 if (!hr->user_name)
55 return -EUNATCH;
56
57 /* We are a bit more restrictive with what we accept as homed-managed user than what we accept in
58 * home records in general. Let's enforce the stricter rule here. */
59 if (!suitable_user_name(hr->user_name))
60 return -EINVAL;
61 if (!uid_is_valid(hr->uid))
62 return -EINVAL;
63
64 /* Insist we are outside of the dynamic and system range */
65 if (uid_is_system(hr->uid) || gid_is_system(user_record_gid(hr)) ||
66 uid_is_dynamic(hr->uid) || gid_is_dynamic(user_record_gid(hr)))
67 return -EADDRNOTAVAIL;
68
69 /* Insist that GID and UID match */
70 if (user_record_gid(hr) != (gid_t) hr->uid)
71 return -EBADSLT;
72
73 /* Similar for the realm */
74 if (hr->realm) {
75 r = suitable_realm(hr->realm);
76 if (r < 0)
77 return r;
78 if (r == 0)
79 return -EINVAL;
80 }
81
82 return 0;
83}
84
85int home_new(Manager *m, UserRecord *hr, const char *sysfs, Home **ret) {
86 _cleanup_(home_freep) Home *home = NULL;
87 _cleanup_free_ char *nm = NULL, *ns = NULL;
88 int r;
89
90 assert(m);
91 assert(hr);
92
93 r = suitable_home_record(hr);
94 if (r < 0)
95 return r;
96
97 if (hashmap_contains(m->homes_by_name, hr->user_name))
98 return -EBUSY;
99
100 if (hashmap_contains(m->homes_by_uid, UID_TO_PTR(hr->uid)))
101 return -EBUSY;
102
103 if (sysfs && hashmap_contains(m->homes_by_sysfs, sysfs))
104 return -EBUSY;
105
106 if (hashmap_size(m->homes_by_name) >= HOME_USERS_MAX)
107 return -EUSERS;
108
109 nm = strdup(hr->user_name);
110 if (!nm)
111 return -ENOMEM;
112
113 if (sysfs) {
114 ns = strdup(sysfs);
115 if (!ns)
116 return -ENOMEM;
117 }
118
119 home = new(Home, 1);
120 if (!home)
121 return -ENOMEM;
122
123 *home = (Home) {
124 .manager = m,
125 .user_name = TAKE_PTR(nm),
126 .uid = hr->uid,
127 .state = _HOME_STATE_INVALID,
128 .worker_stdout_fd = -1,
129 .sysfs = TAKE_PTR(ns),
130 .signed_locally = -1,
131 };
132
133 r = hashmap_put(m->homes_by_name, home->user_name, home);
134 if (r < 0)
135 return r;
136
137 r = hashmap_put(m->homes_by_uid, UID_TO_PTR(home->uid), home);
138 if (r < 0)
139 return r;
140
141 if (home->sysfs) {
142 r = hashmap_put(m->homes_by_sysfs, home->sysfs, home);
143 if (r < 0)
144 return r;
145 }
146
147 r = user_record_clone(hr, USER_RECORD_LOAD_MASK_SECRET, &home->record);
148 if (r < 0)
149 return r;
150
151 (void) bus_manager_emit_auto_login_changed(m);
152 (void) bus_home_emit_change(home);
153
154 if (ret)
155 *ret = TAKE_PTR(home);
156 else
157 TAKE_PTR(home);
158
159 return 0;
160}
161
162Home *home_free(Home *h) {
163
164 if (!h)
165 return NULL;
166
167 if (h->manager) {
168 (void) bus_home_emit_remove(h);
169 (void) bus_manager_emit_auto_login_changed(h->manager);
170
171 if (h->user_name)
172 (void) hashmap_remove_value(h->manager->homes_by_name, h->user_name, h);
173
174 if (uid_is_valid(h->uid))
175 (void) hashmap_remove_value(h->manager->homes_by_uid, UID_TO_PTR(h->uid), h);
176
177 if (h->sysfs)
178 (void) hashmap_remove_value(h->manager->homes_by_sysfs, h->sysfs, h);
179
180 if (h->worker_pid > 0)
181 (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h);
182
183 if (h->manager->gc_focus == h)
184 h->manager->gc_focus = NULL;
185 }
186
187 user_record_unref(h->record);
188 user_record_unref(h->secret);
189
190 h->worker_event_source = sd_event_source_unref(h->worker_event_source);
191 safe_close(h->worker_stdout_fd);
192 free(h->user_name);
193 free(h->sysfs);
194
195 h->ref_event_source_please_suspend = sd_event_source_unref(h->ref_event_source_please_suspend);
196 h->ref_event_source_dont_suspend = sd_event_source_unref(h->ref_event_source_dont_suspend);
197
198 h->pending_operations = ordered_set_free(h->pending_operations);
199 h->pending_event_source = sd_event_source_unref(h->pending_event_source);
200 h->deferred_change_event_source = sd_event_source_unref(h->deferred_change_event_source);
201
202 h->current_operation = operation_unref(h->current_operation);
203
204 return mfree(h);
205}
206
207int home_set_record(Home *h, UserRecord *hr) {
208 _cleanup_(user_record_unrefp) UserRecord *new_hr = NULL;
209 Home *other;
210 int r;
211
212 assert(h);
213 assert(h->user_name);
214 assert(h->record);
215 assert(hr);
216
217 if (user_record_equal(h->record, hr))
218 return 0;
219
220 r = suitable_home_record(hr);
221 if (r < 0)
222 return r;
223
224 if (!user_record_compatible(h->record, hr))
225 return -EREMCHG;
226
227 if (!FLAGS_SET(hr->mask, USER_RECORD_REGULAR) ||
228 FLAGS_SET(hr->mask, USER_RECORD_SECRET))
229 return -EINVAL;
230
231 if (FLAGS_SET(h->record->mask, USER_RECORD_STATUS)) {
232 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
233
234 /* Hmm, the existing record has status fields? If so, copy them over */
235
236 v = json_variant_ref(hr->json);
237 r = json_variant_set_field(&v, "status", json_variant_by_key(h->record->json, "status"));
238 if (r < 0)
239 return r;
240
241 new_hr = user_record_new();
242 if (!new_hr)
243 return -ENOMEM;
244
245 r = user_record_load(new_hr, v, USER_RECORD_LOAD_REFUSE_SECRET);
246 if (r < 0)
247 return r;
248
249 hr = new_hr;
250 }
251
252 other = hashmap_get(h->manager->homes_by_uid, UID_TO_PTR(hr->uid));
253 if (other && other != h)
254 return -EBUSY;
255
256 if (h->uid != hr->uid) {
257 r = hashmap_remove_and_replace(h->manager->homes_by_uid, UID_TO_PTR(h->uid), UID_TO_PTR(hr->uid), h);
258 if (r < 0)
259 return r;
260 }
261
262 user_record_unref(h->record);
263 h->record = user_record_ref(hr);
264 h->uid = h->record->uid;
265
266 /* The updated record might have a different autologin setting, trigger a PropertiesChanged event for it */
267 (void) bus_manager_emit_auto_login_changed(h->manager);
268 (void) bus_home_emit_change(h);
269
270 return 0;
271}
272
273int home_save_record(Home *h) {
274 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
275 _cleanup_free_ char *text = NULL;
276 const char *fn;
277 int r;
278
279 assert(h);
280
281 v = json_variant_ref(h->record->json);
282 r = json_variant_normalize(&v);
283 if (r < 0)
284 log_warning_errno(r, "User record could not be normalized.");
285
286 r = json_variant_format(v, JSON_FORMAT_PRETTY|JSON_FORMAT_NEWLINE, &text);
287 if (r < 0)
288 return r;
289
290 (void) mkdir("/var/lib/systemd/", 0755);
291 (void) mkdir("/var/lib/systemd/home/", 0700);
292
293 fn = strjoina("/var/lib/systemd/home/", h->user_name, ".identity");
294
e4005ffe 295 r = write_string_file(fn, text, WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_MODE_0600|WRITE_STRING_FILE_SYNC);
70a5db58
LP
296 if (r < 0)
297 return r;
298
299 return 0;
300}
301
302int home_unlink_record(Home *h) {
303 const char *fn;
304
305 assert(h);
306
307 fn = strjoina("/var/lib/systemd/home/", h->user_name, ".identity");
308 if (unlink(fn) < 0 && errno != ENOENT)
309 return -errno;
310
311 fn = strjoina("/run/systemd/home/", h->user_name, ".ref");
312 if (unlink(fn) < 0 && errno != ENOENT)
313 return -errno;
314
315 return 0;
316}
317
318static void home_set_state(Home *h, HomeState state) {
319 HomeState old_state, new_state;
320
321 assert(h);
322
323 old_state = home_get_state(h);
324 h->state = state;
325 new_state = home_get_state(h); /* Query the new state, since the 'state' variable might be set to -1,
326 * in which case we synthesize an high-level state on demand */
327
328 log_info("%s: changing state %s → %s", h->user_name,
329 home_state_to_string(old_state),
330 home_state_to_string(new_state));
331
332 if (HOME_STATE_IS_EXECUTING_OPERATION(old_state) && !HOME_STATE_IS_EXECUTING_OPERATION(new_state)) {
333 /* If we just finished executing some operation, process the queue of pending operations. And
334 * enqueue it for GC too. */
335
336 home_schedule_operation(h, NULL, NULL);
337 manager_enqueue_gc(h->manager, h);
338 }
339}
340
341static int home_parse_worker_stdout(int _fd, UserRecord **ret) {
342 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
343 _cleanup_close_ int fd = _fd; /* take possession, even on failure */
344 _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
345 _cleanup_fclose_ FILE *f = NULL;
346 unsigned line, column;
347 struct stat st;
348 int r;
349
350 if (fstat(fd, &st) < 0)
351 return log_error_errno(errno, "Failed to stat stdout fd: %m");
352
353 assert(S_ISREG(st.st_mode));
354
355 if (st.st_size == 0) { /* empty record */
356 *ret = NULL;
357 return 0;
358 }
359
360 if (lseek(fd, SEEK_SET, 0) == (off_t) -1)
361 return log_error_errno(errno, "Failed to seek to beginning of memfd: %m");
362
4fa744a3 363 f = take_fdopen(&fd, "r");
70a5db58
LP
364 if (!f)
365 return log_error_errno(errno, "Failed to reopen memfd: %m");
366
70a5db58
LP
367 if (DEBUG_LOGGING) {
368 _cleanup_free_ char *text = NULL;
369
370 r = read_full_stream(f, &text, NULL);
371 if (r < 0)
372 return log_error_errno(r, "Failed to read from client: %m");
373
374 log_debug("Got from worker: %s", text);
375 rewind(f);
376 }
377
378 r = json_parse_file(f, "stdout", JSON_PARSE_SENSITIVE, &v, &line, &column);
379 if (r < 0)
380 return log_error_errno(r, "Failed to parse identity at %u:%u: %m", line, column);
381
382 hr = user_record_new();
383 if (!hr)
384 return log_oom();
385
386 r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET);
387 if (r < 0)
388 return log_error_errno(r, "Failed to load home record identity: %m");
389
390 *ret = TAKE_PTR(hr);
391 return 1;
392}
393
394static int home_verify_user_record(Home *h, UserRecord *hr, bool *ret_signed_locally, sd_bus_error *ret_error) {
395 int is_signed;
396
397 assert(h);
398 assert(hr);
399 assert(ret_signed_locally);
400
401 is_signed = manager_verify_user_record(h->manager, hr);
402 switch (is_signed) {
403
404 case USER_RECORD_SIGNED_EXCLUSIVE:
405 log_info("Home %s is signed exclusively by our key, accepting.", hr->user_name);
406 *ret_signed_locally = true;
407 return 0;
408
409 case USER_RECORD_SIGNED:
410 log_info("Home %s is signed by our key (and others), accepting.", hr->user_name);
411 *ret_signed_locally = false;
412 return 0;
413
414 case USER_RECORD_FOREIGN:
415 log_info("Home %s is signed by foreign key we like, accepting.", hr->user_name);
416 *ret_signed_locally = false;
417 return 0;
418
419 case USER_RECORD_UNSIGNED:
420 sd_bus_error_setf(ret_error, BUS_ERROR_BAD_SIGNATURE, "User record %s is not signed at all, refusing.", hr->user_name);
421 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Home %s contains user record that is not signed at all, refusing.", hr->user_name);
422
423 case -ENOKEY:
424 sd_bus_error_setf(ret_error, BUS_ERROR_BAD_SIGNATURE, "User record %s is not signed by any known key, refusing.", hr->user_name);
80ace4f2 425 return log_error_errno(is_signed, "Home %s contains user record that is not signed by any known key, refusing.", hr->user_name);
70a5db58
LP
426
427 default:
428 assert(is_signed < 0);
429 return log_error_errno(is_signed, "Failed to verify signature on user record for %s, refusing fixation: %m", hr->user_name);
430 }
431}
432
433static int convert_worker_errno(Home *h, int e, sd_bus_error *error) {
434 /* Converts the error numbers the worker process returned into somewhat sensible dbus errors */
435
436 switch (e) {
437
438 case -EMSGSIZE:
162392b7 439 return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type cannot be shrunk");
70a5db58 440 case -ETXTBSY:
162392b7 441 return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "File systems of this type can only be shrunk offline");
70a5db58
LP
442 case -ERANGE:
443 return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "File system size too small");
444 case -ENOLINK:
445 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "System does not support selected storage backend");
446 case -EPROTONOSUPPORT:
447 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "System does not support selected file system");
448 case -ENOTTY:
449 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Operation not supported on storage backend");
450 case -ESOCKTNOSUPPORT:
451 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Operation not supported on file system");
452 case -ENOKEY:
453 return sd_bus_error_setf(error, BUS_ERROR_BAD_PASSWORD, "Password for home %s is incorrect or not sufficient for authentication.", h->user_name);
454 case -EBADSLT:
455 return sd_bus_error_setf(error, BUS_ERROR_BAD_PASSWORD_AND_NO_TOKEN, "Password for home %s is incorrect or not sufficient, and configured security token not found either.", h->user_name);
456 case -ENOANO:
457 return sd_bus_error_setf(error, BUS_ERROR_TOKEN_PIN_NEEDED, "PIN for security token required.");
458 case -ERFKILL:
459 return sd_bus_error_setf(error, BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED, "Security token requires protected authentication path.");
7b78db28
LP
460 case -EMEDIUMTYPE:
461 return sd_bus_error_setf(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED, "Security token requires user presence.");
462 case -ENOSTR:
463 return sd_bus_error_setf(error, BUS_ERROR_TOKEN_ACTION_TIMEOUT, "Token action timeout. (User was supposed to verify presence or similar, by interacting with the token, and didn't do that in time.)");
70a5db58
LP
464 case -EOWNERDEAD:
465 return sd_bus_error_setf(error, BUS_ERROR_TOKEN_PIN_LOCKED, "PIN of security token locked.");
466 case -ENOLCK:
467 return sd_bus_error_setf(error, BUS_ERROR_TOKEN_BAD_PIN, "Bad PIN of security token.");
468 case -ETOOMANYREFS:
469 return sd_bus_error_setf(error, BUS_ERROR_TOKEN_BAD_PIN_FEW_TRIES_LEFT, "Bad PIN of security token, and only a few tries left.");
470 case -EUCLEAN:
471 return sd_bus_error_setf(error, BUS_ERROR_TOKEN_BAD_PIN_ONE_TRY_LEFT, "Bad PIN of security token, and only one try left.");
472 case -EBUSY:
473 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
474 case -ENOEXEC:
475 return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s is currently not active", h->user_name);
476 case -ENOSPC:
477 return sd_bus_error_setf(error, BUS_ERROR_NO_DISK_SPACE, "Not enough disk space for home %s", h->user_name);
cbffdcec
LP
478 case -EKEYREVOKED:
479 return sd_bus_error_setf(error, BUS_ERROR_HOME_CANT_AUTHENTICATE, "Home %s has no password or other authentication mechanism defined.", h->user_name);
70a5db58
LP
480 }
481
482 return 0;
483}
484
485static void home_count_bad_authentication(Home *h, bool save) {
486 int r;
487
488 assert(h);
489
490 r = user_record_bad_authentication(h->record);
491 if (r < 0) {
492 log_warning_errno(r, "Failed to increase bad authentication counter, ignoring: %m");
493 return;
494 }
495
496 if (save) {
497 r = home_save_record(h);
498 if (r < 0)
499 log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
500 }
501}
502
503static void home_fixate_finish(Home *h, int ret, UserRecord *hr) {
504 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
505 _cleanup_(user_record_unrefp) UserRecord *secret = NULL;
506 bool signed_locally;
507 int r;
508
509 assert(h);
510 assert(IN_SET(h->state, HOME_FIXATING, HOME_FIXATING_FOR_ACTIVATION, HOME_FIXATING_FOR_ACQUIRE));
511
512 secret = TAKE_PTR(h->secret); /* Take possession */
513
514 if (ret < 0) {
515 if (ret == -ENOKEY)
516 (void) home_count_bad_authentication(h, false);
517
518 (void) convert_worker_errno(h, ret, &error);
519 r = log_error_errno(ret, "Fixation failed: %m");
520 goto fail;
521 }
522 if (!hr) {
523 r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Did not receive user record from worker process, fixation failed.");
524 goto fail;
525 }
526
527 r = home_verify_user_record(h, hr, &signed_locally, &error);
528 if (r < 0)
529 goto fail;
530
531 r = home_set_record(h, hr);
532 if (r < 0) {
533 log_error_errno(r, "Failed to update home record: %m");
534 goto fail;
535 }
536
537 h->signed_locally = signed_locally;
538
539 /* When we finished fixating (and don't follow-up with activation), let's count this as good authentication */
540 if (h->state == HOME_FIXATING) {
541 r = user_record_good_authentication(h->record);
542 if (r < 0)
543 log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");
544 }
545
546 r = home_save_record(h);
547 if (r < 0)
548 log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
549
550 if (IN_SET(h->state, HOME_FIXATING_FOR_ACTIVATION, HOME_FIXATING_FOR_ACQUIRE)) {
551
552 r = home_start_work(h, "activate", h->record, secret);
553 if (r < 0) {
554 h->current_operation = operation_result_unref(h->current_operation, r, NULL);
555 home_set_state(h, _HOME_STATE_INVALID);
556 } else
557 home_set_state(h, h->state == HOME_FIXATING_FOR_ACTIVATION ? HOME_ACTIVATING : HOME_ACTIVATING_FOR_ACQUIRE);
558
559 return;
560 }
561
562 log_debug("Fixation of %s completed.", h->user_name);
563
564 h->current_operation = operation_result_unref(h->current_operation, 0, NULL);
565
566 /* Reset the state to "invalid", which makes home_get_state() test if the image exists and returns
567 * HOME_ABSENT vs. HOME_INACTIVE as necessary. */
568 home_set_state(h, _HOME_STATE_INVALID);
569 return;
570
571fail:
572 /* If fixation fails, we stay in unfixated state! */
573 h->current_operation = operation_result_unref(h->current_operation, r, &error);
574 home_set_state(h, HOME_UNFIXATED);
575}
576
577static void home_activate_finish(Home *h, int ret, UserRecord *hr) {
578 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
579 int r;
580
581 assert(h);
582 assert(IN_SET(h->state, HOME_ACTIVATING, HOME_ACTIVATING_FOR_ACQUIRE));
583
584 if (ret < 0) {
585 if (ret == -ENOKEY)
586 home_count_bad_authentication(h, true);
587
588 (void) convert_worker_errno(h, ret, &error);
589 r = log_error_errno(ret, "Activation failed: %m");
590 goto finish;
591 }
592
593 if (hr) {
594 bool signed_locally;
595
596 r = home_verify_user_record(h, hr, &signed_locally, &error);
597 if (r < 0)
598 goto finish;
599
600 r = home_set_record(h, hr);
601 if (r < 0) {
602 log_error_errno(r, "Failed to update home record, ignoring: %m");
603 goto finish;
604 }
605
606 h->signed_locally = signed_locally;
607
608 r = user_record_good_authentication(h->record);
609 if (r < 0)
610 log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");
611
612 r = home_save_record(h);
613 if (r < 0)
614 log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
615 }
616
617 log_debug("Activation of %s completed.", h->user_name);
618 r = 0;
619
620finish:
621 h->current_operation = operation_result_unref(h->current_operation, r, &error);
622 home_set_state(h, _HOME_STATE_INVALID);
623}
624
625static void home_deactivate_finish(Home *h, int ret, UserRecord *hr) {
626 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
627 int r;
628
629 assert(h);
630 assert(h->state == HOME_DEACTIVATING);
631 assert(!hr); /* We don't expect a record on this operation */
632
633 if (ret < 0) {
634 (void) convert_worker_errno(h, ret, &error);
635 r = log_error_errno(ret, "Deactivation of %s failed: %m", h->user_name);
636 goto finish;
637 }
638
639 log_debug("Deactivation of %s completed.", h->user_name);
640 r = 0;
641
642finish:
643 h->current_operation = operation_result_unref(h->current_operation, r, &error);
644 home_set_state(h, _HOME_STATE_INVALID);
645}
646
647static void home_remove_finish(Home *h, int ret, UserRecord *hr) {
648 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
649 Manager *m;
650 int r;
651
652 assert(h);
653 assert(h->state == HOME_REMOVING);
654 assert(!hr); /* We don't expect a record on this operation */
655
656 m = h->manager;
657
658 if (ret < 0 && ret != -EALREADY) {
659 (void) convert_worker_errno(h, ret, &error);
660 r = log_error_errno(ret, "Removing %s failed: %m", h->user_name);
661 goto fail;
662 }
663
664 /* For a couple of storage types we can't delete the actual data storage when called (such as LUKS on
665 * partitions like USB sticks, or so). Sometimes these storage locations are among those we normally
666 * automatically discover in /home or in udev. When such a home is deleted let's hence issue a rescan
667 * after completion, so that "unfixated" entries are rediscovered. */
668 if (!IN_SET(user_record_test_image_path(h->record), USER_TEST_UNDEFINED, USER_TEST_ABSENT))
669 manager_enqueue_rescan(m);
670
671 /* The image is now removed from disk. Now also remove our stored record */
672 r = home_unlink_record(h);
673 if (r < 0) {
674 log_error_errno(r, "Removing record file failed: %m");
675 goto fail;
676 }
677
678 log_debug("Removal of %s completed.", h->user_name);
679 h->current_operation = operation_result_unref(h->current_operation, 0, NULL);
680
681 /* Unload this record from memory too now. */
682 h = home_free(h);
683 return;
684
685fail:
686 h->current_operation = operation_result_unref(h->current_operation, r, &error);
687 home_set_state(h, _HOME_STATE_INVALID);
688}
689
690static void home_create_finish(Home *h, int ret, UserRecord *hr) {
691 int r;
692
693 assert(h);
694 assert(h->state == HOME_CREATING);
695
696 if (ret < 0) {
697 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
698
699 (void) convert_worker_errno(h, ret, &error);
700 log_error_errno(ret, "Operation on %s failed: %m", h->user_name);
701 h->current_operation = operation_result_unref(h->current_operation, ret, &error);
702
703 if (h->unregister_on_failure) {
704 (void) home_unlink_record(h);
705 h = home_free(h);
706 return;
707 }
708
709 home_set_state(h, _HOME_STATE_INVALID);
710 return;
711 }
712
713 if (hr) {
714 r = home_set_record(h, hr);
715 if (r < 0)
716 log_warning_errno(r, "Failed to update home record, ignoring: %m");
717 }
718
719 r = home_save_record(h);
720 if (r < 0)
721 log_warning_errno(r, "Failed to save record to disk, ignoring: %m");
722
723 log_debug("Creation of %s completed.", h->user_name);
724
725 h->current_operation = operation_result_unref(h->current_operation, 0, NULL);
726 home_set_state(h, _HOME_STATE_INVALID);
727}
728
729static void home_change_finish(Home *h, int ret, UserRecord *hr) {
730 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
731 int r;
732
733 assert(h);
734
735 if (ret < 0) {
736 if (ret == -ENOKEY)
737 (void) home_count_bad_authentication(h, true);
738
739 (void) convert_worker_errno(h, ret, &error);
740 r = log_error_errno(ret, "Change operation failed: %m");
741 goto finish;
742 }
743
744 if (hr) {
745 r = home_set_record(h, hr);
746 if (r < 0)
747 log_warning_errno(r, "Failed to update home record, ignoring: %m");
748 else {
749 r = user_record_good_authentication(h->record);
750 if (r < 0)
751 log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");
752
753 r = home_save_record(h);
754 if (r < 0)
755 log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
756 }
757 }
758
759 log_debug("Change operation of %s completed.", h->user_name);
760 r = 0;
761
762finish:
763 h->current_operation = operation_result_unref(h->current_operation, r, &error);
764 home_set_state(h, _HOME_STATE_INVALID);
765}
766
767static void home_locking_finish(Home *h, int ret, UserRecord *hr) {
768 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
769 int r;
770
771 assert(h);
772 assert(h->state == HOME_LOCKING);
773
774 if (ret < 0) {
775 (void) convert_worker_errno(h, ret, &error);
776 r = log_error_errno(ret, "Locking operation failed: %m");
777 goto finish;
778 }
779
780 log_debug("Locking operation of %s completed.", h->user_name);
781 h->current_operation = operation_result_unref(h->current_operation, 0, NULL);
782 home_set_state(h, HOME_LOCKED);
783 return;
784
785finish:
786 /* If a specific home doesn't know the concept of locking, then that's totally OK, don't propagate
787 * the error if we are executing a LockAllHomes() operation. */
788
789 if (h->current_operation->type == OPERATION_LOCK_ALL && r == -ENOTTY)
790 h->current_operation = operation_result_unref(h->current_operation, 0, NULL);
791 else
792 h->current_operation = operation_result_unref(h->current_operation, r, &error);
793
794 home_set_state(h, _HOME_STATE_INVALID);
795}
796
797static void home_unlocking_finish(Home *h, int ret, UserRecord *hr) {
798 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
799 int r;
800
801 assert(h);
802 assert(IN_SET(h->state, HOME_UNLOCKING, HOME_UNLOCKING_FOR_ACQUIRE));
803
804 if (ret < 0) {
805 if (ret == -ENOKEY)
806 (void) home_count_bad_authentication(h, true);
807
808 (void) convert_worker_errno(h, ret, &error);
809 r = log_error_errno(ret, "Unlocking operation failed: %m");
810
811 /* Revert to locked state */
812 home_set_state(h, HOME_LOCKED);
813 h->current_operation = operation_result_unref(h->current_operation, r, &error);
814 return;
815 }
816
817 r = user_record_good_authentication(h->record);
818 if (r < 0)
819 log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");
820 else {
821 r = home_save_record(h);
822 if (r < 0)
823 log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
824 }
825
826 log_debug("Unlocking operation of %s completed.", h->user_name);
827
828 h->current_operation = operation_result_unref(h->current_operation, r, &error);
829 home_set_state(h, _HOME_STATE_INVALID);
830 return;
831}
832
833static void home_authenticating_finish(Home *h, int ret, UserRecord *hr) {
834 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
835 int r;
836
837 assert(h);
838 assert(IN_SET(h->state, HOME_AUTHENTICATING, HOME_AUTHENTICATING_WHILE_ACTIVE, HOME_AUTHENTICATING_FOR_ACQUIRE));
839
840 if (ret < 0) {
841 if (ret == -ENOKEY)
842 (void) home_count_bad_authentication(h, true);
843
844 (void) convert_worker_errno(h, ret, &error);
845 r = log_error_errno(ret, "Authentication failed: %m");
846 goto finish;
847 }
848
849 if (hr) {
850 r = home_set_record(h, hr);
851 if (r < 0)
852 log_warning_errno(r, "Failed to update home record, ignoring: %m");
853 else {
854 r = user_record_good_authentication(h->record);
855 if (r < 0)
856 log_warning_errno(r, "Failed to increase good authentication counter, ignoring: %m");
857
858 r = home_save_record(h);
859 if (r < 0)
860 log_warning_errno(r, "Failed to write home record to disk, ignoring: %m");
861 }
862 }
863
864 log_debug("Authentication of %s completed.", h->user_name);
865 r = 0;
866
867finish:
868 h->current_operation = operation_result_unref(h->current_operation, r, &error);
869 home_set_state(h, _HOME_STATE_INVALID);
870}
871
872static int home_on_worker_process(sd_event_source *s, const siginfo_t *si, void *userdata) {
873 _cleanup_(user_record_unrefp) UserRecord *hr = NULL;
874 Home *h = userdata;
875 int ret;
876
877 assert(s);
878 assert(si);
879 assert(h);
880
881 assert(h->worker_pid == si->si_pid);
882 assert(h->worker_event_source);
883 assert(h->worker_stdout_fd >= 0);
884
885 (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h);
886
887 h->worker_pid = 0;
888 h->worker_event_source = sd_event_source_unref(h->worker_event_source);
889
890 if (si->si_code != CLD_EXITED) {
891 assert(IN_SET(si->si_code, CLD_KILLED, CLD_DUMPED));
892 ret = log_debug_errno(SYNTHETIC_ERRNO(EPROTO), "Worker process died abnormally with signal %s.", signal_to_string(si->si_status));
893 } else if (si->si_status != EXIT_SUCCESS) {
894 /* If we received an error code via sd_notify(), use it */
895 if (h->worker_error_code != 0)
896 ret = log_debug_errno(h->worker_error_code, "Worker reported error code %s.", errno_to_name(h->worker_error_code));
897 else
898 ret = log_debug_errno(SYNTHETIC_ERRNO(EPROTO), "Worker exited with exit code %i.", si->si_status);
899 } else
900 ret = home_parse_worker_stdout(TAKE_FD(h->worker_stdout_fd), &hr);
901
902 h->worker_stdout_fd = safe_close(h->worker_stdout_fd);
903
904 switch (h->state) {
905
906 case HOME_FIXATING:
907 case HOME_FIXATING_FOR_ACTIVATION:
908 case HOME_FIXATING_FOR_ACQUIRE:
909 home_fixate_finish(h, ret, hr);
910 break;
911
912 case HOME_ACTIVATING:
913 case HOME_ACTIVATING_FOR_ACQUIRE:
914 home_activate_finish(h, ret, hr);
915 break;
916
917 case HOME_DEACTIVATING:
918 home_deactivate_finish(h, ret, hr);
919 break;
920
921 case HOME_LOCKING:
922 home_locking_finish(h, ret, hr);
923 break;
924
925 case HOME_UNLOCKING:
926 case HOME_UNLOCKING_FOR_ACQUIRE:
927 home_unlocking_finish(h, ret, hr);
928 break;
929
930 case HOME_CREATING:
931 home_create_finish(h, ret, hr);
932 break;
933
934 case HOME_REMOVING:
935 home_remove_finish(h, ret, hr);
936 break;
937
938 case HOME_UPDATING:
939 case HOME_UPDATING_WHILE_ACTIVE:
940 case HOME_RESIZING:
941 case HOME_RESIZING_WHILE_ACTIVE:
942 case HOME_PASSWD:
943 case HOME_PASSWD_WHILE_ACTIVE:
944 home_change_finish(h, ret, hr);
945 break;
946
947 case HOME_AUTHENTICATING:
948 case HOME_AUTHENTICATING_WHILE_ACTIVE:
949 case HOME_AUTHENTICATING_FOR_ACQUIRE:
950 home_authenticating_finish(h, ret, hr);
951 break;
952
953 default:
954 assert_not_reached("Unexpected state after worker exited");
955 }
956
957 return 0;
958}
959
960static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord *secret) {
961 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
962 _cleanup_(erase_and_freep) char *formatted = NULL;
963 _cleanup_close_ int stdin_fd = -1, stdout_fd = -1;
964 pid_t pid = 0;
965 int r;
966
967 assert(h);
968 assert(verb);
969 assert(hr);
970
971 if (h->worker_pid != 0)
972 return -EBUSY;
973
974 assert(h->worker_stdout_fd < 0);
975 assert(!h->worker_event_source);
976
977 v = json_variant_ref(hr->json);
978
979 if (secret) {
980 JsonVariant *sub = NULL;
981
982 sub = json_variant_by_key(secret->json, "secret");
983 if (!sub)
984 return -ENOKEY;
985
986 r = json_variant_set_field(&v, "secret", sub);
987 if (r < 0)
988 return r;
989 }
990
991 r = json_variant_format(v, 0, &formatted);
992 if (r < 0)
993 return r;
994
995 stdin_fd = acquire_data_fd(formatted, strlen(formatted), 0);
996 if (stdin_fd < 0)
997 return stdin_fd;
998
999 log_debug("Sending to worker: %s", formatted);
1000
1001 stdout_fd = memfd_create("homework-stdout", MFD_CLOEXEC);
1002 if (stdout_fd < 0)
1003 return -errno;
1004
1005 r = safe_fork_full("(sd-homework)",
1006 (int[]) { stdin_fd, stdout_fd }, 2,
1007 FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG, &pid);
1008 if (r < 0)
1009 return r;
1010 if (r == 0) {
c06bcd4d
LP
1011 const char *homework;
1012
70a5db58
LP
1013 /* Child */
1014
1015 if (setenv("NOTIFY_SOCKET", "/run/systemd/home/notify", 1) < 0) {
1016 log_error_errno(errno, "Failed to set $NOTIFY_SOCKET: %m");
1017 _exit(EXIT_FAILURE);
1018 }
1019
c76dd733
LP
1020 if (h->manager->default_storage >= 0)
1021 if (setenv("SYSTEMD_HOME_DEFAULT_STORAGE", user_storage_to_string(h->manager->default_storage), 1) < 0) {
1022 log_error_errno(errno, "Failed to set $SYSTEMD_HOME_DEFAULT_STORAGE: %m");
1023 _exit(EXIT_FAILURE);
1024 }
1025
1026 if (h->manager->default_file_system_type)
1027 if (setenv("SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE", h->manager->default_file_system_type, 1) < 0) {
1028 log_error_errno(errno, "Failed to set $SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE: %m");
1029 _exit(EXIT_FAILURE);
1030 }
1031
70a5db58
LP
1032 r = rearrange_stdio(stdin_fd, stdout_fd, STDERR_FILENO);
1033 if (r < 0) {
1034 log_error_errno(r, "Failed to rearrange stdin/stdout/stderr: %m");
1035 _exit(EXIT_FAILURE);
1036 }
1037
1038 stdin_fd = stdout_fd = -1; /* have been invalidated by rearrange_stdio() */
1039
c06bcd4d
LP
1040 /* Allow overriding the homework path via an environment variable, to make debugging
1041 * easier. */
1042 homework = getenv("SYSTEMD_HOMEWORK_PATH") ?: SYSTEMD_HOMEWORK_PATH;
1043
1044 execl(homework, homework, verb, NULL);
70a5db58
LP
1045 log_error_errno(errno, "Failed to invoke " SYSTEMD_HOMEWORK_PATH ": %m");
1046 _exit(EXIT_FAILURE);
1047 }
1048
1049 r = sd_event_add_child(h->manager->event, &h->worker_event_source, pid, WEXITED, home_on_worker_process, h);
1050 if (r < 0)
1051 return r;
1052
1053 (void) sd_event_source_set_description(h->worker_event_source, "worker");
1054
1055 r = hashmap_put(h->manager->homes_by_worker_pid, PID_TO_PTR(pid), h);
1056 if (r < 0) {
1057 h->worker_event_source = sd_event_source_unref(h->worker_event_source);
1058 return r;
1059 }
1060
1061 h->worker_stdout_fd = TAKE_FD(stdout_fd);
1062 h->worker_pid = pid;
1063 h->worker_error_code = 0;
1064
1065 return 0;
1066}
1067
1068static int home_ratelimit(Home *h, sd_bus_error *error) {
1069 int r, ret;
1070
1071 assert(h);
1072
1073 ret = user_record_ratelimit(h->record);
1074 if (ret < 0)
1075 return ret;
1076
1077 if (h->state != HOME_UNFIXATED) {
1078 r = home_save_record(h);
1079 if (r < 0)
1080 log_warning_errno(r, "Failed to save updated record, ignoring: %m");
1081 }
1082
1083 if (ret == 0) {
1084 char buf[FORMAT_TIMESPAN_MAX];
1085 usec_t t, n;
1086
1087 n = now(CLOCK_REALTIME);
1088 t = user_record_ratelimit_next_try(h->record);
1089
1090 if (t != USEC_INFINITY && t > n)
1091 return sd_bus_error_setf(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT, "Too many login attempts, please try again in %s!",
1092 format_timespan(buf, sizeof(buf), t - n, USEC_PER_SEC));
1093
1094 return sd_bus_error_setf(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT, "Too many login attempts, please try again later.");
1095 }
1096
1097 return 0;
1098}
1099
1100static int home_fixate_internal(
1101 Home *h,
1102 UserRecord *secret,
1103 HomeState for_state,
1104 sd_bus_error *error) {
1105
1106 int r;
1107
1108 assert(h);
1109 assert(IN_SET(for_state, HOME_FIXATING, HOME_FIXATING_FOR_ACTIVATION, HOME_FIXATING_FOR_ACQUIRE));
1110
1111 r = home_start_work(h, "inspect", h->record, secret);
1112 if (r < 0)
1113 return r;
1114
1115 if (for_state == HOME_FIXATING_FOR_ACTIVATION) {
1116 /* Remember the secret data, since we need it for the activation again, later on. */
1117 user_record_unref(h->secret);
1118 h->secret = user_record_ref(secret);
1119 }
1120
1121 home_set_state(h, for_state);
1122 return 0;
1123}
1124
1125int home_fixate(Home *h, UserRecord *secret, sd_bus_error *error) {
1126 int r;
1127
1128 assert(h);
1129
1130 switch (home_get_state(h)) {
1131 case HOME_ABSENT:
1132 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
1133 case HOME_INACTIVE:
1134 case HOME_ACTIVE:
1135 case HOME_LOCKED:
1136 return sd_bus_error_setf(error, BUS_ERROR_HOME_ALREADY_FIXATED, "Home %s is already fixated.", h->user_name);
1137 case HOME_UNFIXATED:
1138 break;
1139 default:
1140 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1141 }
1142
1143 r = home_ratelimit(h, error);
1144 if (r < 0)
1145 return r;
1146
1147 return home_fixate_internal(h, secret, HOME_FIXATING, error);
1148}
1149
1150static int home_activate_internal(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) {
1151 int r;
1152
1153 assert(h);
1154 assert(IN_SET(for_state, HOME_ACTIVATING, HOME_ACTIVATING_FOR_ACQUIRE));
1155
1156 r = home_start_work(h, "activate", h->record, secret);
1157 if (r < 0)
1158 return r;
1159
1160 home_set_state(h, for_state);
1161 return 0;
1162}
1163
1164int home_activate(Home *h, UserRecord *secret, sd_bus_error *error) {
1165 int r;
1166
1167 assert(h);
1168
1169 switch (home_get_state(h)) {
1170 case HOME_UNFIXATED:
1171 return home_fixate_internal(h, secret, HOME_FIXATING_FOR_ACTIVATION, error);
1172 case HOME_ABSENT:
1173 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
1174 case HOME_ACTIVE:
1175 return sd_bus_error_setf(error, BUS_ERROR_HOME_ALREADY_ACTIVE, "Home %s is already active.", h->user_name);
1176 case HOME_LOCKED:
1177 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1178 case HOME_INACTIVE:
1179 break;
1180 default:
1181 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1182 }
1183
1184 r = home_ratelimit(h, error);
1185 if (r < 0)
1186 return r;
1187
1188 return home_activate_internal(h, secret, HOME_ACTIVATING, error);
1189}
1190
1191static int home_authenticate_internal(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) {
1192 int r;
1193
1194 assert(h);
1195 assert(IN_SET(for_state, HOME_AUTHENTICATING, HOME_AUTHENTICATING_WHILE_ACTIVE, HOME_AUTHENTICATING_FOR_ACQUIRE));
1196
1197 r = home_start_work(h, "inspect", h->record, secret);
1198 if (r < 0)
1199 return r;
1200
1201 home_set_state(h, for_state);
1202 return 0;
1203}
1204
1205int home_authenticate(Home *h, UserRecord *secret, sd_bus_error *error) {
1206 HomeState state;
1207 int r;
1208
1209 assert(h);
1210
1211 state = home_get_state(h);
1212 switch (state) {
1213 case HOME_ABSENT:
1214 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
1215 case HOME_LOCKED:
1216 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1217 case HOME_UNFIXATED:
1218 case HOME_INACTIVE:
1219 case HOME_ACTIVE:
1220 break;
1221 default:
1222 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1223 }
1224
1225 r = home_ratelimit(h, error);
1226 if (r < 0)
1227 return r;
1228
1229 return home_authenticate_internal(h, secret, state == HOME_ACTIVE ? HOME_AUTHENTICATING_WHILE_ACTIVE : HOME_AUTHENTICATING, error);
1230}
1231
1232static int home_deactivate_internal(Home *h, bool force, sd_bus_error *error) {
1233 int r;
1234
1235 assert(h);
1236
1237 r = home_start_work(h, force ? "deactivate-force" : "deactivate", h->record, NULL);
1238 if (r < 0)
1239 return r;
1240
1241 home_set_state(h, HOME_DEACTIVATING);
1242 return 0;
1243}
1244
1245int home_deactivate(Home *h, bool force, sd_bus_error *error) {
1246 assert(h);
1247
1248 switch (home_get_state(h)) {
1249 case HOME_UNFIXATED:
1250 case HOME_ABSENT:
1251 case HOME_INACTIVE:
1252 return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s not active.", h->user_name);
1253 case HOME_LOCKED:
1254 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1255 case HOME_ACTIVE:
1256 break;
1257 default:
1258 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1259 }
1260
1261 return home_deactivate_internal(h, force, error);
1262}
1263
1264int home_create(Home *h, UserRecord *secret, sd_bus_error *error) {
1265 int r;
1266
1267 assert(h);
1268
1269 switch (home_get_state(h)) {
1270 case HOME_INACTIVE:
1271 if (h->record->storage < 0)
1272 break; /* if no storage is defined we don't know what precisely to look for, hence
1273 * HOME_INACTIVE is OK in that case too. */
1274
1275 if (IN_SET(user_record_test_image_path(h->record), USER_TEST_MAYBE, USER_TEST_UNDEFINED))
1276 break; /* And if the image path test isn't conclusive, let's also go on */
1277
1278 _fallthrough_;
1279 case HOME_UNFIXATED:
1280 return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Home of user %s already exists.", h->user_name);
1281 case HOME_ABSENT:
1282 break;
1283 case HOME_ACTIVE:
1284 case HOME_LOCKED:
1285 default:
1286 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
1287 }
1288
1289 if (h->record->enforce_password_policy == false)
1290 log_debug("Password quality check turned off for account, skipping.");
1291 else {
1292 r = quality_check_password(h->record, secret, error);
1293 if (r < 0)
1294 return r;
1295 }
1296
1297 r = home_start_work(h, "create", h->record, secret);
1298 if (r < 0)
1299 return r;
1300
1301 home_set_state(h, HOME_CREATING);
1302 return 0;
1303}
1304
1305int home_remove(Home *h, sd_bus_error *error) {
1306 HomeState state;
1307 int r;
1308
1309 assert(h);
1310
1311 state = home_get_state(h);
1312 switch (state) {
1313 case HOME_ABSENT: /* If the home directory is absent, then this is just like unregistering */
1314 return home_unregister(h, error);
1315 case HOME_LOCKED:
1316 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1317 case HOME_UNFIXATED:
1318 case HOME_INACTIVE:
1319 break;
1320 case HOME_ACTIVE:
1321 default:
1322 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
1323 }
1324
1325 r = home_start_work(h, "remove", h->record, NULL);
1326 if (r < 0)
1327 return r;
1328
1329 home_set_state(h, HOME_REMOVING);
1330 return 0;
1331}
1332
1333static int user_record_extend_with_binding(UserRecord *hr, UserRecord *with_binding, UserRecordLoadFlags flags, UserRecord **ret) {
1334 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
1335 _cleanup_(user_record_unrefp) UserRecord *nr = NULL;
1336 JsonVariant *binding;
1337 int r;
1338
1339 assert(hr);
1340 assert(with_binding);
1341 assert(ret);
1342
1343 assert_se(v = json_variant_ref(hr->json));
1344
1345 binding = json_variant_by_key(with_binding->json, "binding");
1346 if (binding) {
1347 r = json_variant_set_field(&v, "binding", binding);
1348 if (r < 0)
1349 return r;
1350 }
1351
1352 nr = user_record_new();
1353 if (!nr)
1354 return -ENOMEM;
1355
1356 r = user_record_load(nr, v, flags);
1357 if (r < 0)
1358 return r;
1359
1360 *ret = TAKE_PTR(nr);
1361 return 0;
1362}
1363
7b78db28
LP
1364static int home_update_internal(
1365 Home *h,
1366 const char *verb,
1367 UserRecord *hr,
1368 UserRecord *secret,
1369 sd_bus_error *error) {
1370
70a5db58
LP
1371 _cleanup_(user_record_unrefp) UserRecord *new_hr = NULL, *saved_secret = NULL, *signed_hr = NULL;
1372 int r, c;
1373
1374 assert(h);
1375 assert(verb);
1376 assert(hr);
1377
1378 if (!user_record_compatible(hr, h->record))
1379 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Updated user record is not compatible with existing one.");
1380 c = user_record_compare_last_change(hr, h->record); /* refuse downgrades */
1381 if (c < 0)
1382 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_DOWNGRADE, "Refusing to update to older home record.");
1383
1384 if (!secret && FLAGS_SET(hr->mask, USER_RECORD_SECRET)) {
1385 r = user_record_clone(hr, USER_RECORD_EXTRACT_SECRET, &saved_secret);
1386 if (r < 0)
1387 return r;
1388
1389 secret = saved_secret;
1390 }
1391
1392 r = manager_verify_user_record(h->manager, hr);
1393 switch (r) {
1394
1395 case USER_RECORD_UNSIGNED:
1396 if (h->signed_locally <= 0) /* If the existing record is not owned by us, don't accept an
1397 * unsigned new record. i.e. only implicitly sign new records
1398 * that where previously signed by us too. */
1399 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);
1400
1401 /* The updated record is not signed, then do so now */
1402 r = manager_sign_user_record(h->manager, hr, &signed_hr, error);
1403 if (r < 0)
1404 return r;
1405
1406 hr = signed_hr;
1407 break;
1408
1409 case USER_RECORD_SIGNED_EXCLUSIVE:
1410 case USER_RECORD_SIGNED:
1411 case USER_RECORD_FOREIGN:
1412 /* Has already been signed. Great! */
1413 break;
1414
1415 case -ENOKEY:
1416 default:
1417 return r;
1418 }
1419
1420 r = user_record_extend_with_binding(hr, h->record, USER_RECORD_LOAD_MASK_SECRET, &new_hr);
1421 if (r < 0)
1422 return r;
1423
1424 if (c == 0) {
1425 /* different payload but same lastChangeUSec field? That's not cool! */
1426
1427 r = user_record_masked_equal(new_hr, h->record, USER_RECORD_REGULAR|USER_RECORD_PRIVILEGED|USER_RECORD_PER_MACHINE);
1428 if (r < 0)
1429 return r;
1430 if (r == 0)
1431 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Home record different but timestamp remained the same, refusing.");
1432 }
1433
1434 r = home_start_work(h, verb, new_hr, secret);
1435 if (r < 0)
1436 return r;
1437
1438 return 0;
1439}
1440
1441int home_update(Home *h, UserRecord *hr, sd_bus_error *error) {
1442 HomeState state;
1443 int r;
1444
1445 assert(h);
1446 assert(hr);
1447
1448 state = home_get_state(h);
1449 switch (state) {
1450 case HOME_UNFIXATED:
1451 return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
1452 case HOME_ABSENT:
1453 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
1454 case HOME_LOCKED:
1455 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1456 case HOME_INACTIVE:
1457 case HOME_ACTIVE:
1458 break;
1459 default:
1460 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1461 }
1462
1463 r = home_ratelimit(h, error);
1464 if (r < 0)
1465 return r;
1466
1467 r = home_update_internal(h, "update", hr, NULL, error);
1468 if (r < 0)
1469 return r;
1470
1471 home_set_state(h, state == HOME_ACTIVE ? HOME_UPDATING_WHILE_ACTIVE : HOME_UPDATING);
1472 return 0;
1473}
1474
1475int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *error) {
1476 _cleanup_(user_record_unrefp) UserRecord *c = NULL;
1477 HomeState state;
1478 int r;
1479
1480 assert(h);
1481
1482 state = home_get_state(h);
1483 switch (state) {
1484 case HOME_UNFIXATED:
1485 return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
1486 case HOME_ABSENT:
1487 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
1488 case HOME_LOCKED:
1489 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1490 case HOME_INACTIVE:
1491 case HOME_ACTIVE:
1492 break;
1493 default:
1494 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1495 }
1496
1497 r = home_ratelimit(h, error);
1498 if (r < 0)
1499 return r;
1500
1501 if (disk_size == UINT64_MAX || disk_size == h->record->disk_size) {
1502 if (h->record->disk_size == UINT64_MAX)
80ace4f2 1503 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "No disk size to resize to specified.");
70a5db58
LP
1504
1505 c = user_record_ref(h->record); /* Shortcut if size is unspecified or matches the record */
1506 } else {
1507 _cleanup_(user_record_unrefp) UserRecord *signed_c = NULL;
1508
1509 if (h->signed_locally <= 0) /* Don't allow changing of records not signed only by us */
1510 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);
1511
1512 r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET, &c);
1513 if (r < 0)
1514 return r;
1515
1516 r = user_record_set_disk_size(c, disk_size);
1517 if (r == -ERANGE)
1518 return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "Requested size for home %s out of acceptable range.", h->user_name);
1519 if (r < 0)
1520 return r;
1521
1522 r = user_record_update_last_changed(c, false);
1523 if (r == -ECHRNG)
1524 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Record last change time of %s is newer than current time, cannot update.", h->user_name);
1525 if (r < 0)
1526 return r;
1527
1528 r = manager_sign_user_record(h->manager, c, &signed_c, error);
1529 if (r < 0)
1530 return r;
1531
1532 user_record_unref(c);
1533 c = TAKE_PTR(signed_c);
1534 }
1535
1536 r = home_update_internal(h, "resize", c, secret, error);
1537 if (r < 0)
1538 return r;
1539
1540 home_set_state(h, state == HOME_ACTIVE ? HOME_RESIZING_WHILE_ACTIVE : HOME_RESIZING);
1541 return 0;
1542}
1543
1544static int home_may_change_password(
1545 Home *h,
1546 sd_bus_error *error) {
1547
1548 int r;
1549
1550 assert(h);
1551
1552 r = user_record_test_password_change_required(h->record);
1553 if (IN_SET(r, -EKEYREVOKED, -EOWNERDEAD, -EKEYEXPIRED))
86b52a39 1554 return 0; /* expired in some form, but changing is allowed */
70a5db58
LP
1555 if (IN_SET(r, -EKEYREJECTED, -EROFS))
1556 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Expiration settings of account %s do not allow changing of password.", h->user_name);
1557 if (r < 0)
1558 return log_error_errno(r, "Failed to test password expiry: %m");
1559
1560 return 0; /* not expired */
1561}
1562
1563int home_passwd(Home *h,
1564 UserRecord *new_secret,
1565 UserRecord *old_secret,
1566 sd_bus_error *error) {
1567
1568 _cleanup_(user_record_unrefp) UserRecord *c = NULL, *merged_secret = NULL, *signed_c = NULL;
1569 HomeState state;
1570 int r;
1571
1572 assert(h);
1573
1574 if (h->signed_locally <= 0) /* Don't allow changing of records not signed only by us */
1575 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);
1576
1577 state = home_get_state(h);
1578 switch (state) {
1579 case HOME_UNFIXATED:
1580 return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
1581 case HOME_ABSENT:
1582 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
1583 case HOME_LOCKED:
1584 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1585 case HOME_INACTIVE:
1586 case HOME_ACTIVE:
1587 break;
1588 default:
1589 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1590 }
1591
1592 r = home_ratelimit(h, error);
1593 if (r < 0)
1594 return r;
1595
1596 r = home_may_change_password(h, error);
1597 if (r < 0)
1598 return r;
1599
1600 r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET, &c);
1601 if (r < 0)
1602 return r;
1603
1604 merged_secret = user_record_new();
1605 if (!merged_secret)
1606 return -ENOMEM;
1607
1608 r = user_record_merge_secret(merged_secret, old_secret);
1609 if (r < 0)
1610 return r;
1611
1612 r = user_record_merge_secret(merged_secret, new_secret);
1613 if (r < 0)
1614 return r;
1615
1616 if (!strv_isempty(new_secret->password)) {
1617 /* Update the password only if one is specified, otherwise let's just reuse the old password
1618 * data. This is useful as a way to propagate updated user records into the LUKS backends
1619 * properly. */
1620
1621 r = user_record_make_hashed_password(c, new_secret->password, /* extend = */ false);
1622 if (r < 0)
1623 return r;
1624
1625 r = user_record_set_password_change_now(c, -1 /* remove */);
1626 if (r < 0)
1627 return r;
1628 }
1629
1630 r = user_record_update_last_changed(c, true);
1631 if (r == -ECHRNG)
1632 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Record last change time of %s is newer than current time, cannot update.", h->user_name);
1633 if (r < 0)
1634 return r;
1635
1636 r = manager_sign_user_record(h->manager, c, &signed_c, error);
1637 if (r < 0)
1638 return r;
1639
1640 if (c->enforce_password_policy == false)
1641 log_debug("Password quality check turned off for account, skipping.");
1642 else {
1643 r = quality_check_password(c, merged_secret, error);
1644 if (r < 0)
1645 return r;
1646 }
1647
1648 r = home_update_internal(h, "passwd", signed_c, merged_secret, error);
1649 if (r < 0)
1650 return r;
1651
1652 home_set_state(h, state == HOME_ACTIVE ? HOME_PASSWD_WHILE_ACTIVE : HOME_PASSWD);
1653 return 0;
1654}
1655
1656int home_unregister(Home *h, sd_bus_error *error) {
1657 int r;
1658
1659 assert(h);
1660
1661 switch (home_get_state(h)) {
1662 case HOME_UNFIXATED:
1663 return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s is not registered.", h->user_name);
1664 case HOME_LOCKED:
1665 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1666 case HOME_ABSENT:
1667 case HOME_INACTIVE:
1668 break;
1669 case HOME_ACTIVE:
1670 default:
1671 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "Home %s is currently being used, or an operation on home %s is currently being executed.", h->user_name, h->user_name);
1672 }
1673
1674 r = home_unlink_record(h);
1675 if (r < 0)
1676 return r;
1677
1678 /* And destroy the whole entry. The caller needs to be prepared for that. */
1679 h = home_free(h);
1680 return 1;
1681}
1682
1683int home_lock(Home *h, sd_bus_error *error) {
1684 int r;
1685
1686 assert(h);
1687
1688 switch (home_get_state(h)) {
1689 case HOME_UNFIXATED:
1690 case HOME_ABSENT:
1691 case HOME_INACTIVE:
1692 return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s is not active.", h->user_name);
1693 case HOME_LOCKED:
1694 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is already locked.", h->user_name);
1695 case HOME_ACTIVE:
1696 break;
1697 default:
1698 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1699 }
1700
1701 r = home_start_work(h, "lock", h->record, NULL);
1702 if (r < 0)
1703 return r;
1704
1705 home_set_state(h, HOME_LOCKING);
1706 return 0;
1707}
1708
1709static int home_unlock_internal(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) {
1710 int r;
1711
1712 assert(h);
1713 assert(IN_SET(for_state, HOME_UNLOCKING, HOME_UNLOCKING_FOR_ACQUIRE));
1714
1715 r = home_start_work(h, "unlock", h->record, secret);
1716 if (r < 0)
1717 return r;
1718
1719 home_set_state(h, for_state);
1720 return 0;
1721}
1722
1723int home_unlock(Home *h, UserRecord *secret, sd_bus_error *error) {
1724 int r;
1725 assert(h);
1726
1727 r = home_ratelimit(h, error);
1728 if (r < 0)
1729 return r;
1730
1731 switch (home_get_state(h)) {
1732 case HOME_UNFIXATED:
1733 case HOME_ABSENT:
1734 case HOME_INACTIVE:
1735 case HOME_ACTIVE:
1736 return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_LOCKED, "Home %s is not locked.", h->user_name);
1737 case HOME_LOCKED:
1738 break;
1739 default:
1740 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1741 }
1742
1743 return home_unlock_internal(h, secret, HOME_UNLOCKING, error);
1744}
1745
1746HomeState home_get_state(Home *h) {
1747 assert(h);
1748
1749 /* When the state field is initialized, it counts. */
1750 if (h->state >= 0)
1751 return h->state;
1752
1753 /* Otherwise, let's see if the home directory is mounted. If so, we assume for sure the home
1754 * directory is active */
1755 if (user_record_test_home_directory(h->record) == USER_TEST_MOUNTED)
1756 return HOME_ACTIVE;
1757
1758 /* And if we see the image being gone, we report this as absent */
1759 if (user_record_test_image_path(h->record) == USER_TEST_ABSENT)
1760 return HOME_ABSENT;
1761
1762 /* And for all other cases we return "inactive". */
1763 return HOME_INACTIVE;
1764}
1765
1766void home_process_notify(Home *h, char **l) {
1767 const char *e;
1768 int error;
1769 int r;
1770
1771 assert(h);
1772
1773 e = strv_env_get(l, "ERRNO");
1774 if (!e) {
1775 log_debug("Got notify message lacking ERRNO= field, ignoring.");
1776 return;
1777 }
1778
1779 r = safe_atoi(e, &error);
1780 if (r < 0) {
162392b7 1781 log_debug_errno(r, "Failed to parse received error number, ignoring: %s", e);
70a5db58
LP
1782 return;
1783 }
1784 if (error <= 0) {
1785 log_debug("Error number is out of range: %i", error);
1786 return;
1787 }
1788
1789 h->worker_error_code = error;
1790}
1791
1792int home_killall(Home *h) {
1793 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1794 _cleanup_free_ char *unit = NULL;
1795 int r;
1796
1797 assert(h);
1798
1799 if (!uid_is_valid(h->uid))
1800 return 0;
1801
1802 assert(h->uid > 0); /* We never should be UID 0 */
1803
1804 /* Let's kill everything matching the specified UID */
1805 r = safe_fork("(sd-killer)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG, NULL);
1806 if (r < 0)
1807 return r;
1808 if (r == 0) {
1809 gid_t gid;
1810
1811 /* Child */
1812
1813 gid = user_record_gid(h->record);
1814 if (setresgid(gid, gid, gid) < 0) {
1815 log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid);
1816 _exit(EXIT_FAILURE);
1817 }
1818
1819 if (setgroups(0, NULL) < 0) {
1820 log_error_errno(errno, "Failed to reset auxiliary groups list: %m");
1821 _exit(EXIT_FAILURE);
1822 }
1823
1824 if (setresuid(h->uid, h->uid, h->uid) < 0) {
1825 log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", h->uid);
1826 _exit(EXIT_FAILURE);
1827 }
1828
1829 if (kill(-1, SIGKILL) < 0) {
1830 log_error_errno(errno, "Failed to kill all processes of UID " UID_FMT ": %m", h->uid);
1831 _exit(EXIT_FAILURE);
1832 }
1833
1834 _exit(EXIT_SUCCESS);
1835 }
1836
1837 /* Let's also kill everything in the user's slice */
1838 if (asprintf(&unit, "user-" UID_FMT ".slice", h->uid) < 0)
1839 return log_oom();
1840
1841 r = sd_bus_call_method(
1842 h->manager->bus,
1843 "org.freedesktop.systemd1",
1844 "/org/freedesktop/systemd1",
1845 "org.freedesktop.systemd1.Manager",
1846 "KillUnit",
1847 &error,
1848 NULL,
1849 "ssi", unit, "all", SIGKILL);
1850 if (r < 0)
1851 log_full_errno(sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ? LOG_DEBUG : LOG_WARNING,
1852 r, "Failed to kill login processes of user, ignoring: %s", bus_error_message(&error, r));
1853
1854 return 1;
1855}
1856
1857static int home_get_disk_status_luks(
1858 Home *h,
1859 HomeState state,
1860 uint64_t *ret_disk_size,
1861 uint64_t *ret_disk_usage,
1862 uint64_t *ret_disk_free,
1863 uint64_t *ret_disk_ceiling,
1864 uint64_t *ret_disk_floor) {
1865
1866 uint64_t disk_size = UINT64_MAX, disk_usage = UINT64_MAX, disk_free = UINT64_MAX,
1867 disk_ceiling = UINT64_MAX, disk_floor = UINT64_MAX,
1868 stat_used = UINT64_MAX, fs_size = UINT64_MAX, header_size = 0;
1869
1870 struct statfs sfs;
1871 const char *hd;
1872 int r;
1873
1874 assert(h);
1875 assert(ret_disk_size);
1876 assert(ret_disk_usage);
1877 assert(ret_disk_free);
1878 assert(ret_disk_ceiling);
1879
1880 if (state != HOME_ABSENT) {
1881 const char *ip;
1882
1883 ip = user_record_image_path(h->record);
1884 if (ip) {
1885 struct stat st;
1886
1887 if (stat(ip, &st) < 0)
1888 log_debug_errno(errno, "Failed to stat() %s, ignoring: %m", ip);
1889 else if (S_ISREG(st.st_mode)) {
1890 _cleanup_free_ char *parent = NULL;
1891
1892 disk_size = st.st_size;
1893 stat_used = st.st_blocks * 512;
1894
1895 parent = dirname_malloc(ip);
1896 if (!parent)
1897 return log_oom();
1898
1899 if (statfs(parent, &sfs) < 0)
1900 log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", parent);
1901 else
1902 disk_ceiling = stat_used + sfs.f_bsize * sfs.f_bavail;
1903
1904 } else if (S_ISBLK(st.st_mode)) {
1905 _cleanup_free_ char *szbuf = NULL;
1906 char p[SYS_BLOCK_PATH_MAX("/size")];
1907
1908 /* Let's read the size off sysfs, so that we don't have to open the device */
1909 xsprintf_sys_block_path(p, "/size", st.st_rdev);
1910 r = read_one_line_file(p, &szbuf);
1911 if (r < 0)
1912 log_debug_errno(r, "Failed to read %s, ignoring: %m", p);
1913 else {
1914 uint64_t sz;
1915
1916 r = safe_atou64(szbuf, &sz);
1917 if (r < 0)
1918 log_debug_errno(r, "Failed to parse %s, ignoring: %s", p, szbuf);
1919 else
1920 disk_size = sz * 512;
1921 }
1922 } else
1923 log_debug("Image path is not a block device or regular file, not able to acquire size.");
1924 }
1925 }
1926
1927 if (!HOME_STATE_IS_ACTIVE(state))
1928 goto finish;
1929
1930 hd = user_record_home_directory(h->record);
1931 if (!hd)
1932 goto finish;
1933
1934 if (statfs(hd, &sfs) < 0) {
80ace4f2 1935 log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", hd);
70a5db58
LP
1936 goto finish;
1937 }
1938
1939 disk_free = sfs.f_bsize * sfs.f_bavail;
1940 fs_size = sfs.f_bsize * sfs.f_blocks;
1941 if (disk_size != UINT64_MAX && disk_size > fs_size)
1942 header_size = disk_size - fs_size;
1943
1944 /* We take a perspective from the user here (as opposed to from the host): the used disk space is the
1945 * difference from the limit and what's free. This makes a difference if sparse mode is not used: in
1946 * that case the image is pre-allocated and thus appears all used from the host PoV but is not used
1947 * up at all yet from the user's PoV.
1948 *
1949 * That said, we use use the stat() reported loopback file size as upper boundary: our footprint can
1950 * never be larger than what we take up on the lowest layers. */
1951
1952 if (disk_size != UINT64_MAX && disk_size > disk_free) {
1953 disk_usage = disk_size - disk_free;
1954
1955 if (stat_used != UINT64_MAX && disk_usage > stat_used)
1956 disk_usage = stat_used;
1957 } else
1958 disk_usage = stat_used;
1959
1960 /* If we have the magic, determine floor preferably by magic */
1961 disk_floor = minimal_size_by_fs_magic(sfs.f_type) + header_size;
1962
1963finish:
1964 /* If we don't know the magic, go by file system name */
1965 if (disk_floor == UINT64_MAX)
1966 disk_floor = minimal_size_by_fs_name(user_record_file_system_type(h->record));
1967
1968 *ret_disk_size = disk_size;
1969 *ret_disk_usage = disk_usage;
1970 *ret_disk_free = disk_free;
1971 *ret_disk_ceiling = disk_ceiling;
1972 *ret_disk_floor = disk_floor;
1973
1974 return 0;
1975}
1976
1977static int home_get_disk_status_directory(
1978 Home *h,
1979 HomeState state,
1980 uint64_t *ret_disk_size,
1981 uint64_t *ret_disk_usage,
1982 uint64_t *ret_disk_free,
1983 uint64_t *ret_disk_ceiling,
1984 uint64_t *ret_disk_floor) {
1985
1986 uint64_t disk_size = UINT64_MAX, disk_usage = UINT64_MAX, disk_free = UINT64_MAX,
1987 disk_ceiling = UINT64_MAX, disk_floor = UINT64_MAX;
1988 struct statfs sfs;
1989 struct dqblk req;
1990 const char *path = NULL;
1991 int r;
1992
1993 assert(ret_disk_size);
1994 assert(ret_disk_usage);
1995 assert(ret_disk_free);
1996 assert(ret_disk_ceiling);
1997 assert(ret_disk_floor);
1998
1999 if (HOME_STATE_IS_ACTIVE(state))
2000 path = user_record_home_directory(h->record);
2001
2002 if (!path) {
2003 if (state == HOME_ABSENT)
2004 goto finish;
2005
2006 path = user_record_image_path(h->record);
2007 }
2008
2009 if (!path)
2010 goto finish;
2011
2012 if (statfs(path, &sfs) < 0)
2013 log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", path);
2014 else {
2015 disk_free = sfs.f_bsize * sfs.f_bavail;
2016 disk_size = sfs.f_bsize * sfs.f_blocks;
2017
2018 /* We don't initialize disk_usage from statfs() data here, since the device is likely not used
2019 * by us alone, and disk_usage should only reflect our own use. */
2020 }
2021
2022 if (IN_SET(h->record->storage, USER_CLASSIC, USER_DIRECTORY, USER_SUBVOLUME)) {
2023
2024 r = btrfs_is_subvol(path);
2025 if (r < 0)
2026 log_debug_errno(r, "Failed to determine whether %s is a btrfs subvolume: %m", path);
2027 else if (r > 0) {
2028 BtrfsQuotaInfo qi;
2029
2030 r = btrfs_subvol_get_subtree_quota(path, 0, &qi);
2031 if (r < 0)
2032 log_debug_errno(r, "Failed to query btrfs subtree quota, ignoring: %m");
2033 else {
2034 disk_usage = qi.referenced;
2035
2036 if (disk_free != UINT64_MAX) {
2037 disk_ceiling = qi.referenced + disk_free;
2038
2039 if (disk_size != UINT64_MAX && disk_ceiling > disk_size)
2040 disk_ceiling = disk_size;
2041 }
2042
2043 if (qi.referenced_max != UINT64_MAX) {
2044 if (disk_size != UINT64_MAX)
2045 disk_size = MIN(qi.referenced_max, disk_size);
2046 else
2047 disk_size = qi.referenced_max;
2048 }
2049
2050 if (disk_size != UINT64_MAX) {
2051 if (disk_size > disk_usage)
2052 disk_free = disk_size - disk_usage;
2053 else
2054 disk_free = 0;
2055 }
2056 }
2057
2058 goto finish;
2059 }
2060 }
2061
2062 if (IN_SET(h->record->storage, USER_CLASSIC, USER_DIRECTORY, USER_FSCRYPT)) {
2063 r = quotactl_path(QCMD_FIXED(Q_GETQUOTA, USRQUOTA), path, h->uid, &req);
2064 if (r < 0) {
2065 if (ERRNO_IS_NOT_SUPPORTED(r)) {
2066 log_debug_errno(r, "No UID quota support on %s.", path);
2067 goto finish;
2068 }
2069
2070 if (r != -ESRCH) {
2071 log_debug_errno(r, "Failed to query disk quota for UID " UID_FMT ": %m", h->uid);
2072 goto finish;
2073 }
2074
2075 disk_usage = 0; /* No record of this user? then nothing was used */
2076 } else {
2077 if (FLAGS_SET(req.dqb_valid, QIF_SPACE) && disk_free != UINT64_MAX) {
2078 disk_ceiling = req.dqb_curspace + disk_free;
2079
2080 if (disk_size != UINT64_MAX && disk_ceiling > disk_size)
2081 disk_ceiling = disk_size;
2082 }
2083
2084 if (FLAGS_SET(req.dqb_valid, QIF_BLIMITS)) {
2085 uint64_t q;
2086
2087 /* Take the minimum of the quota and the available disk space here */
2088 q = req.dqb_bhardlimit * QIF_DQBLKSIZE;
2089 if (disk_size != UINT64_MAX)
2090 disk_size = MIN(disk_size, q);
2091 else
2092 disk_size = q;
2093 }
2094 if (FLAGS_SET(req.dqb_valid, QIF_SPACE)) {
2095 disk_usage = req.dqb_curspace;
2096
2097 if (disk_size != UINT64_MAX) {
2098 if (disk_size > disk_usage)
2099 disk_free = disk_size - disk_usage;
2100 else
2101 disk_free = 0;
2102 }
2103 }
2104 }
2105 }
2106
2107finish:
2108 *ret_disk_size = disk_size;
2109 *ret_disk_usage = disk_usage;
2110 *ret_disk_free = disk_free;
2111 *ret_disk_ceiling = disk_ceiling;
2112 *ret_disk_floor = disk_floor;
2113
2114 return 0;
2115}
2116
2117int home_augment_status(
2118 Home *h,
2119 UserRecordLoadFlags flags,
2120 UserRecord **ret) {
2121
2122 uint64_t disk_size = UINT64_MAX, disk_usage = UINT64_MAX, disk_free = UINT64_MAX, disk_ceiling = UINT64_MAX, disk_floor = UINT64_MAX;
2123 _cleanup_(json_variant_unrefp) JsonVariant *j = NULL, *v = NULL, *m = NULL, *status = NULL;
2124 _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
2125 char ids[SD_ID128_STRING_MAX];
2126 HomeState state;
2127 sd_id128_t id;
2128 int r;
2129
2130 assert(h);
2131 assert(ret);
2132
2133 /* We are supposed to add this, this can't be on hence. */
2134 assert(!FLAGS_SET(flags, USER_RECORD_STRIP_STATUS));
2135
2136 r = sd_id128_get_machine(&id);
2137 if (r < 0)
2138 return r;
2139
2140 state = home_get_state(h);
2141
2142 switch (h->record->storage) {
2143
2144 case USER_LUKS:
2145 r = home_get_disk_status_luks(h, state, &disk_size, &disk_usage, &disk_free, &disk_ceiling, &disk_floor);
2146 if (r < 0)
2147 return r;
2148
2149 break;
2150
2151 case USER_CLASSIC:
2152 case USER_DIRECTORY:
2153 case USER_SUBVOLUME:
2154 case USER_FSCRYPT:
2155 case USER_CIFS:
2156 r = home_get_disk_status_directory(h, state, &disk_size, &disk_usage, &disk_free, &disk_ceiling, &disk_floor);
2157 if (r < 0)
2158 return r;
2159
2160 break;
2161
2162 default:
2163 ; /* unset */
2164 }
2165
2166 if (disk_floor == UINT64_MAX || (disk_usage != UINT64_MAX && disk_floor < disk_usage))
2167 disk_floor = disk_usage;
2168 if (disk_floor == UINT64_MAX || disk_floor < USER_DISK_SIZE_MIN)
2169 disk_floor = USER_DISK_SIZE_MIN;
2170 if (disk_ceiling == UINT64_MAX || disk_ceiling > USER_DISK_SIZE_MAX)
2171 disk_ceiling = USER_DISK_SIZE_MAX;
2172
2173 r = json_build(&status,
2174 JSON_BUILD_OBJECT(
2175 JSON_BUILD_PAIR("state", JSON_BUILD_STRING(home_state_to_string(state))),
2176 JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.Home")),
2177 JSON_BUILD_PAIR_CONDITION(disk_size != UINT64_MAX, "diskSize", JSON_BUILD_UNSIGNED(disk_size)),
2178 JSON_BUILD_PAIR_CONDITION(disk_usage != UINT64_MAX, "diskUsage", JSON_BUILD_UNSIGNED(disk_usage)),
2179 JSON_BUILD_PAIR_CONDITION(disk_free != UINT64_MAX, "diskFree", JSON_BUILD_UNSIGNED(disk_free)),
2180 JSON_BUILD_PAIR_CONDITION(disk_ceiling != UINT64_MAX, "diskCeiling", JSON_BUILD_UNSIGNED(disk_ceiling)),
2181 JSON_BUILD_PAIR_CONDITION(disk_floor != UINT64_MAX, "diskFloor", JSON_BUILD_UNSIGNED(disk_floor)),
2182 JSON_BUILD_PAIR_CONDITION(h->signed_locally >= 0, "signedLocally", JSON_BUILD_BOOLEAN(h->signed_locally))
2183 ));
2184 if (r < 0)
2185 return r;
2186
2187 j = json_variant_ref(h->record->json);
2188 v = json_variant_ref(json_variant_by_key(j, "status"));
2189 m = json_variant_ref(json_variant_by_key(v, sd_id128_to_string(id, ids)));
2190
2191 r = json_variant_filter(&m, STRV_MAKE("diskSize", "diskUsage", "diskFree", "diskCeiling", "diskFloor", "signedLocally"));
2192 if (r < 0)
2193 return r;
2194
2195 r = json_variant_merge(&m, status);
2196 if (r < 0)
2197 return r;
2198
2199 r = json_variant_set_field(&v, ids, m);
2200 if (r < 0)
2201 return r;
2202
2203 r = json_variant_set_field(&j, "status", v);
2204 if (r < 0)
2205 return r;
2206
2207 ur = user_record_new();
2208 if (!ur)
2209 return -ENOMEM;
2210
2211 r = user_record_load(ur, j, flags);
2212 if (r < 0)
2213 return r;
2214
2215 ur->incomplete =
2216 FLAGS_SET(h->record->mask, USER_RECORD_PRIVILEGED) &&
2217 !FLAGS_SET(ur->mask, USER_RECORD_PRIVILEGED);
2218
2219 *ret = TAKE_PTR(ur);
2220 return 0;
2221}
2222
2223static int on_home_ref_eof(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2224 _cleanup_(operation_unrefp) Operation *o = NULL;
2225 Home *h = userdata;
2226
2227 assert(s);
2228 assert(h);
2229
2230 if (h->ref_event_source_please_suspend == s)
2231 h->ref_event_source_please_suspend = sd_event_source_disable_unref(h->ref_event_source_please_suspend);
2232
2233 if (h->ref_event_source_dont_suspend == s)
2234 h->ref_event_source_dont_suspend = sd_event_source_disable_unref(h->ref_event_source_dont_suspend);
2235
2236 if (h->ref_event_source_dont_suspend || h->ref_event_source_please_suspend)
2237 return 0;
2238
2239 log_info("Got notification that all sessions of user %s ended, deactivating automatically.", h->user_name);
2240
2241 o = operation_new(OPERATION_PIPE_EOF, NULL);
2242 if (!o) {
2243 log_oom();
2244 return 0;
2245 }
2246
2247 home_schedule_operation(h, o, NULL);
2248 return 0;
2249}
2250
2251int home_create_fifo(Home *h, bool please_suspend) {
2252 _cleanup_close_ int ret_fd = -1;
2253 sd_event_source **ss;
2254 const char *fn, *suffix;
2255 int r;
2256
2257 assert(h);
2258
2259 if (please_suspend) {
2260 suffix = ".please-suspend";
2261 ss = &h->ref_event_source_please_suspend;
2262 } else {
2263 suffix = ".dont-suspend";
2264 ss = &h->ref_event_source_dont_suspend;
2265 }
2266
2267 fn = strjoina("/run/systemd/home/", h->user_name, suffix);
2268
2269 if (!*ss) {
2270 _cleanup_close_ int ref_fd = -1;
2271
2272 (void) mkdir("/run/systemd/home/", 0755);
2273 if (mkfifo(fn, 0600) < 0 && errno != EEXIST)
2274 return log_error_errno(errno, "Failed to create FIFO %s: %m", fn);
2275
2276 ref_fd = open(fn, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
2277 if (ref_fd < 0)
2278 return log_error_errno(errno, "Failed to open FIFO %s for reading: %m", fn);
2279
2280 r = sd_event_add_io(h->manager->event, ss, ref_fd, 0, on_home_ref_eof, h);
2281 if (r < 0)
2282 return log_error_errno(r, "Failed to allocate reference FIFO event source: %m");
2283
2284 (void) sd_event_source_set_description(*ss, "acquire-ref");
2285
2286 r = sd_event_source_set_priority(*ss, SD_EVENT_PRIORITY_IDLE-1);
2287 if (r < 0)
2288 return r;
2289
2290 r = sd_event_source_set_io_fd_own(*ss, true);
2291 if (r < 0)
2292 return log_error_errno(r, "Failed to pass ownership of FIFO event fd to event source: %m");
2293
2294 TAKE_FD(ref_fd);
2295 }
2296
2297 ret_fd = open(fn, O_WRONLY|O_CLOEXEC|O_NONBLOCK);
2298 if (ret_fd < 0)
2299 return log_error_errno(errno, "Failed to open FIFO %s for writing: %m", fn);
2300
2301 return TAKE_FD(ret_fd);
2302}
2303
2304static int home_dispatch_acquire(Home *h, Operation *o) {
2305 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2306 int (*call)(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) = NULL;
2307 HomeState for_state;
2308 int r;
2309
2310 assert(h);
2311 assert(o);
2312 assert(o->type == OPERATION_ACQUIRE);
2313
2314 switch (home_get_state(h)) {
2315
2316 case HOME_UNFIXATED:
2317 for_state = HOME_FIXATING_FOR_ACQUIRE;
2318 call = home_fixate_internal;
2319 break;
2320
2321 case HOME_ABSENT:
2322 r = sd_bus_error_setf(&error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
2323 break;
2324
2325 case HOME_INACTIVE:
2326 for_state = HOME_ACTIVATING_FOR_ACQUIRE;
2327 call = home_activate_internal;
2328 break;
2329
2330 case HOME_ACTIVE:
2331 for_state = HOME_AUTHENTICATING_FOR_ACQUIRE;
2332 call = home_authenticate_internal;
2333 break;
2334
2335 case HOME_LOCKED:
2336 for_state = HOME_UNLOCKING_FOR_ACQUIRE;
2337 call = home_unlock_internal;
2338 break;
2339
2340 default:
2341 /* All other cases means we are currently executing an operation, which means the job remains
2342 * pending. */
2343 return 0;
2344 }
2345
2346 assert(!h->current_operation);
2347
2348 if (call) {
2349 r = home_ratelimit(h, &error);
2350 if (r >= 0)
2351 r = call(h, o->secret, for_state, &error);
2352 }
2353
2354 if (r != 0) /* failure or completed */
2355 operation_result(o, r, &error);
2356 else /* ongoing */
2357 h->current_operation = operation_ref(o);
2358
2359 return 1;
2360}
2361
2362static int home_dispatch_release(Home *h, Operation *o) {
2363 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2364 int r;
2365
2366 assert(h);
2367 assert(o);
2368 assert(o->type == OPERATION_RELEASE);
2369
2370 if (h->ref_event_source_dont_suspend || h->ref_event_source_please_suspend)
2371 /* If there's now a reference again, then let's abort the release attempt */
2372 r = sd_bus_error_setf(&error, BUS_ERROR_HOME_BUSY, "Home %s is currently referenced.", h->user_name);
2373 else {
2374 switch (home_get_state(h)) {
2375
2376 case HOME_UNFIXATED:
2377 case HOME_ABSENT:
2378 case HOME_INACTIVE:
a60416f3 2379 r = 1; /* done */
70a5db58
LP
2380 break;
2381
2382 case HOME_LOCKED:
2383 r = sd_bus_error_setf(&error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
2384 break;
2385
2386 case HOME_ACTIVE:
2387 r = home_deactivate_internal(h, false, &error);
2388 break;
2389
2390 default:
2391 /* All other cases means we are currently executing an operation, which means the job remains
2392 * pending. */
2393 return 0;
2394 }
2395 }
2396
2397 assert(!h->current_operation);
2398
a60416f3 2399 if (r != 0) /* failure or completed */
70a5db58
LP
2400 operation_result(o, r, &error);
2401 else /* ongoing */
2402 h->current_operation = operation_ref(o);
2403
2404 return 1;
2405}
2406
2407static int home_dispatch_lock_all(Home *h, Operation *o) {
2408 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2409 int r;
2410
2411 assert(h);
2412 assert(o);
2413 assert(o->type == OPERATION_LOCK_ALL);
2414
2415 switch (home_get_state(h)) {
2416
2417 case HOME_UNFIXATED:
2418 case HOME_ABSENT:
2419 case HOME_INACTIVE:
2420 log_info("Home %s is not active, no locking necessary.", h->user_name);
a60416f3 2421 r = 1; /* done */
70a5db58
LP
2422 break;
2423
2424 case HOME_LOCKED:
2425 log_info("Home %s is already locked.", h->user_name);
a60416f3 2426 r = 1; /* done */
70a5db58
LP
2427 break;
2428
2429 case HOME_ACTIVE:
2430 log_info("Locking home %s.", h->user_name);
2431 r = home_lock(h, &error);
2432 break;
2433
2434 default:
2435 /* All other cases means we are currently executing an operation, which means the job remains
2436 * pending. */
2437 return 0;
2438 }
2439
2440 assert(!h->current_operation);
2441
2442 if (r != 0) /* failure or completed */
2443 operation_result(o, r, &error);
2444 else /* ongoing */
2445 h->current_operation = operation_ref(o);
2446
2447 return 1;
2448}
2449
2450static int home_dispatch_pipe_eof(Home *h, Operation *o) {
2451 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2452 int r;
2453
2454 assert(h);
2455 assert(o);
2456 assert(o->type == OPERATION_PIPE_EOF);
2457
2458 if (h->ref_event_source_please_suspend || h->ref_event_source_dont_suspend)
2459 return 1; /* Hmm, there's a reference again, let's cancel this */
2460
2461 switch (home_get_state(h)) {
2462
2463 case HOME_UNFIXATED:
2464 case HOME_ABSENT:
2465 case HOME_INACTIVE:
2466 log_info("Home %s already deactivated, no automatic deactivation needed.", h->user_name);
2467 break;
2468
2469 case HOME_DEACTIVATING:
2470 log_info("Home %s is already being deactivated, automatic deactivated unnecessary.", h->user_name);
2471 break;
2472
2473 case HOME_ACTIVE:
2474 r = home_deactivate_internal(h, false, &error);
2475 if (r < 0)
2476 log_warning_errno(r, "Failed to deactivate %s, ignoring: %s", h->user_name, bus_error_message(&error, r));
2477 break;
2478
2479 case HOME_LOCKED:
2480 default:
2481 /* If the device is locked or any operation is being executed, let's leave this pending */
2482 return 0;
2483 }
2484
2485 /* Note that we don't call operation_fail() or operation_success() here, because this kind of
2486 * operation has no message associated with it, and thus there's no need to propagate success. */
2487
2488 assert(!o->message);
2489 return 1;
2490}
2491
2492static int home_dispatch_deactivate_force(Home *h, Operation *o) {
2493 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2494 int r;
2495
2496 assert(h);
2497 assert(o);
2498 assert(o->type == OPERATION_DEACTIVATE_FORCE);
2499
2500 switch (home_get_state(h)) {
2501
2502 case HOME_UNFIXATED:
2503 case HOME_ABSENT:
2504 case HOME_INACTIVE:
2505 log_debug("Home %s already deactivated, no forced deactivation due to unplug needed.", h->user_name);
2506 break;
2507
2508 case HOME_DEACTIVATING:
2509 log_debug("Home %s is already being deactivated, forced deactivation due to unplug unnecessary.", h->user_name);
2510 break;
2511
2512 case HOME_ACTIVE:
2513 case HOME_LOCKED:
2514 r = home_deactivate_internal(h, true, &error);
2515 if (r < 0)
2516 log_warning_errno(r, "Failed to forcibly deactivate %s, ignoring: %s", h->user_name, bus_error_message(&error, r));
2517 break;
2518
2519 default:
2520 /* If any operation is being executed, let's leave this pending */
2521 return 0;
2522 }
2523
2524 /* Note that we don't call operation_fail() or operation_success() here, because this kind of
2525 * operation has no message associated with it, and thus there's no need to propagate success. */
2526
2527 assert(!o->message);
2528 return 1;
2529}
2530
2531static int on_pending(sd_event_source *s, void *userdata) {
2532 Home *h = userdata;
2533 Operation *o;
2534 int r;
2535
2536 assert(s);
2537 assert(h);
2538
2539 o = ordered_set_first(h->pending_operations);
2540 if (o) {
2541 static int (* const operation_table[_OPERATION_MAX])(Home *h, Operation *o) = {
2542 [OPERATION_ACQUIRE] = home_dispatch_acquire,
2543 [OPERATION_RELEASE] = home_dispatch_release,
2544 [OPERATION_LOCK_ALL] = home_dispatch_lock_all,
2545 [OPERATION_PIPE_EOF] = home_dispatch_pipe_eof,
2546 [OPERATION_DEACTIVATE_FORCE] = home_dispatch_deactivate_force,
2547 };
2548
2549 assert(operation_table[o->type]);
2550 r = operation_table[o->type](h, o);
2551 if (r != 0) {
2552 /* The operation completed, let's remove it from the pending list, and exit while
2553 * leaving the event source enabled as it is. */
2554 assert_se(ordered_set_remove(h->pending_operations, o) == o);
2555 operation_unref(o);
2556 return 0;
2557 }
2558 }
2559
2560 /* Nothing to do anymore, let's turn off this event source */
2561 r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
2562 if (r < 0)
2563 return log_error_errno(r, "Failed to disable event source: %m");
2564
2565 return 0;
2566}
2567
2568int home_schedule_operation(Home *h, Operation *o, sd_bus_error *error) {
2569 int r;
2570
2571 assert(h);
2572
2573 if (o) {
2574 if (ordered_set_size(h->pending_operations) >= PENDING_OPERATIONS_MAX)
2575 return sd_bus_error_setf(error, BUS_ERROR_TOO_MANY_OPERATIONS, "Too many client operations requested");
2576
2577 r = ordered_set_ensure_allocated(&h->pending_operations, &operation_hash_ops);
2578 if (r < 0)
2579 return r;
2580
2581 r = ordered_set_put(h->pending_operations, o);
2582 if (r < 0)
2583 return r;
2584
2585 operation_ref(o);
2586 }
2587
2588 if (!h->pending_event_source) {
2589 r = sd_event_add_defer(h->manager->event, &h->pending_event_source, on_pending, h);
2590 if (r < 0)
2591 return log_error_errno(r, "Failed to allocate pending defer event source: %m");
2592
2593 (void) sd_event_source_set_description(h->pending_event_source, "pending");
2594
2595 r = sd_event_source_set_priority(h->pending_event_source, SD_EVENT_PRIORITY_IDLE);
2596 if (r < 0)
2597 return r;
2598 }
2599
2600 r = sd_event_source_set_enabled(h->pending_event_source, SD_EVENT_ON);
2601 if (r < 0)
2602 return log_error_errno(r, "Failed to trigger pending event source: %m");
2603
2604 return 0;
2605}
2606
2607static int home_get_image_path_seat(Home *h, char **ret) {
2608 _cleanup_(sd_device_unrefp) sd_device *d = NULL;
2609 _cleanup_free_ char *c = NULL;
2610 const char *ip, *seat;
2611 struct stat st;
2612 int r;
2613
2614 assert(h);
2615
2616 if (user_record_storage(h->record) != USER_LUKS)
2617 return -ENXIO;
2618
2619 ip = user_record_image_path(h->record);
2620 if (!ip)
2621 return -ENXIO;
2622
2623 if (!path_startswith(ip, "/dev/"))
2624 return -ENXIO;
2625
2626 if (stat(ip, &st) < 0)
2627 return -errno;
2628
2629 if (!S_ISBLK(st.st_mode))
2630 return -ENOTBLK;
2631
2632 r = sd_device_new_from_devnum(&d, 'b', st.st_rdev);
2633 if (r < 0)
2634 return r;
2635
2636 r = sd_device_get_property_value(d, "ID_SEAT", &seat);
2637 if (r == -ENOENT) /* no property means seat0 */
2638 seat = "seat0";
2639 else if (r < 0)
2640 return r;
2641
2642 c = strdup(seat);
2643 if (!c)
2644 return -ENOMEM;
2645
2646 *ret = TAKE_PTR(c);
2647 return 0;
2648}
2649
2650int home_auto_login(Home *h, char ***ret_seats) {
2651 _cleanup_free_ char *seat = NULL, *seat2 = NULL;
2652
2653 assert(h);
2654 assert(ret_seats);
2655
2656 (void) home_get_image_path_seat(h, &seat);
2657
2658 if (h->record->auto_login > 0 && !streq_ptr(seat, "seat0")) {
2659 /* For now, when the auto-login boolean is set for a user, let's make it mean
2660 * "seat0". Eventually we can extend the concept and allow configuration of any kind of seat,
2661 * but let's keep simple initially, most likely the feature is interesting on single-user
2662 * systems anyway, only.
2663 *
2664 * We filter out users marked for auto-login in we know for sure their home directory is
2665 * absent. */
2666
2667 if (user_record_test_image_path(h->record) != USER_TEST_ABSENT) {
2668 seat2 = strdup("seat0");
2669 if (!seat2)
2670 return -ENOMEM;
2671 }
2672 }
2673
2674 if (seat || seat2) {
2675 _cleanup_strv_free_ char **list = NULL;
2676 size_t i = 0;
2677
2678 list = new(char*, 3);
2679 if (!list)
2680 return -ENOMEM;
2681
2682 if (seat)
2683 list[i++] = TAKE_PTR(seat);
2684 if (seat2)
2685 list[i++] = TAKE_PTR(seat2);
2686
2687 list[i] = NULL;
2688 *ret_seats = TAKE_PTR(list);
2689 return 1;
2690 }
2691
2692 *ret_seats = NULL;
2693 return 0;
2694}
2695
2696int home_set_current_message(Home *h, sd_bus_message *m) {
2697 assert(h);
2698
2699 if (!m)
2700 return 0;
2701
2702 if (h->current_operation)
2703 return -EBUSY;
2704
2705 h->current_operation = operation_new(OPERATION_IMMEDIATE, m);
2706 if (!h->current_operation)
2707 return -ENOMEM;
2708
2709 return 1;
2710}
2711
2712static const char* const home_state_table[_HOME_STATE_MAX] = {
2713 [HOME_UNFIXATED] = "unfixated",
2714 [HOME_ABSENT] = "absent",
2715 [HOME_INACTIVE] = "inactive",
2716 [HOME_FIXATING] = "fixating",
2717 [HOME_FIXATING_FOR_ACTIVATION] = "fixating-for-activation",
2718 [HOME_FIXATING_FOR_ACQUIRE] = "fixating-for-acquire",
2719 [HOME_ACTIVATING] = "activating",
2720 [HOME_ACTIVATING_FOR_ACQUIRE] = "activating-for-acquire",
2721 [HOME_DEACTIVATING] = "deactivating",
2722 [HOME_ACTIVE] = "active",
2723 [HOME_LOCKING] = "locking",
2724 [HOME_LOCKED] = "locked",
2725 [HOME_UNLOCKING] = "unlocking",
2726 [HOME_UNLOCKING_FOR_ACQUIRE] = "unlocking-for-acquire",
2727 [HOME_CREATING] = "creating",
2728 [HOME_REMOVING] = "removing",
2729 [HOME_UPDATING] = "updating",
2730 [HOME_UPDATING_WHILE_ACTIVE] = "updating-while-active",
2731 [HOME_RESIZING] = "resizing",
2732 [HOME_RESIZING_WHILE_ACTIVE] = "resizing-while-active",
2733 [HOME_PASSWD] = "passwd",
2734 [HOME_PASSWD_WHILE_ACTIVE] = "passwd-while-active",
2735 [HOME_AUTHENTICATING] = "authenticating",
2736 [HOME_AUTHENTICATING_WHILE_ACTIVE] = "authenticating-while-active",
2737 [HOME_AUTHENTICATING_FOR_ACQUIRE] = "authenticating-for-acquire",
2738};
2739
2740DEFINE_STRING_TABLE_LOOKUP(home_state, HomeState);