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