]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/home/homed-home.c
homed: make clean that --storage=directory --image-path=/dev/some-block-device is...
[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)) {
f9d525ae
LP
1283 case HOME_INACTIVE: {
1284 int t;
1285
70a5db58
LP
1286 if (h->record->storage < 0)
1287 break; /* if no storage is defined we don't know what precisely to look for, hence
1288 * HOME_INACTIVE is OK in that case too. */
1289
f9d525ae
LP
1290 t = user_record_test_image_path(h->record);
1291 if (IN_SET(t, USER_TEST_MAYBE, USER_TEST_UNDEFINED))
70a5db58
LP
1292 break; /* And if the image path test isn't conclusive, let's also go on */
1293
f9d525ae
LP
1294 if (IN_SET(t, -EBADFD, -ENOTDIR))
1295 return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Selected home image of user %s already exists or has wrong inode type.", h->user_name);
1296
1297 return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Selected home image of user %s already exists.", h->user_name);
1298 }
70a5db58 1299 case HOME_UNFIXATED:
9be99f81 1300 case HOME_DIRTY:
70a5db58
LP
1301 return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Home of user %s already exists.", h->user_name);
1302 case HOME_ABSENT:
1303 break;
1304 case HOME_ACTIVE:
1305 case HOME_LOCKED:
1306 default:
1307 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);
1308 }
1309
1310 if (h->record->enforce_password_policy == false)
1311 log_debug("Password quality check turned off for account, skipping.");
1312 else {
679badd7 1313 r = user_record_quality_check_password(h->record, secret, error);
70a5db58
LP
1314 if (r < 0)
1315 return r;
1316 }
1317
1318 r = home_start_work(h, "create", h->record, secret);
1319 if (r < 0)
1320 return r;
1321
1322 home_set_state(h, HOME_CREATING);
1323 return 0;
1324}
1325
1326int home_remove(Home *h, sd_bus_error *error) {
1327 HomeState state;
1328 int r;
1329
1330 assert(h);
1331
1332 state = home_get_state(h);
1333 switch (state) {
1334 case HOME_ABSENT: /* If the home directory is absent, then this is just like unregistering */
1335 return home_unregister(h, error);
1336 case HOME_LOCKED:
1337 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1338 case HOME_UNFIXATED:
1339 case HOME_INACTIVE:
9be99f81 1340 case HOME_DIRTY:
70a5db58
LP
1341 break;
1342 case HOME_ACTIVE:
1343 default:
1344 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);
1345 }
1346
1347 r = home_start_work(h, "remove", h->record, NULL);
1348 if (r < 0)
1349 return r;
1350
1351 home_set_state(h, HOME_REMOVING);
1352 return 0;
1353}
1354
1355static int user_record_extend_with_binding(UserRecord *hr, UserRecord *with_binding, UserRecordLoadFlags flags, UserRecord **ret) {
1356 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
1357 _cleanup_(user_record_unrefp) UserRecord *nr = NULL;
1358 JsonVariant *binding;
1359 int r;
1360
1361 assert(hr);
1362 assert(with_binding);
1363 assert(ret);
1364
1365 assert_se(v = json_variant_ref(hr->json));
1366
1367 binding = json_variant_by_key(with_binding->json, "binding");
1368 if (binding) {
1369 r = json_variant_set_field(&v, "binding", binding);
1370 if (r < 0)
1371 return r;
1372 }
1373
1374 nr = user_record_new();
1375 if (!nr)
1376 return -ENOMEM;
1377
1378 r = user_record_load(nr, v, flags);
1379 if (r < 0)
1380 return r;
1381
1382 *ret = TAKE_PTR(nr);
1383 return 0;
1384}
1385
7b78db28
LP
1386static int home_update_internal(
1387 Home *h,
1388 const char *verb,
1389 UserRecord *hr,
1390 UserRecord *secret,
1391 sd_bus_error *error) {
1392
70a5db58
LP
1393 _cleanup_(user_record_unrefp) UserRecord *new_hr = NULL, *saved_secret = NULL, *signed_hr = NULL;
1394 int r, c;
1395
1396 assert(h);
1397 assert(verb);
1398 assert(hr);
1399
1400 if (!user_record_compatible(hr, h->record))
1401 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Updated user record is not compatible with existing one.");
1402 c = user_record_compare_last_change(hr, h->record); /* refuse downgrades */
1403 if (c < 0)
1404 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_DOWNGRADE, "Refusing to update to older home record.");
1405
1406 if (!secret && FLAGS_SET(hr->mask, USER_RECORD_SECRET)) {
1407 r = user_record_clone(hr, USER_RECORD_EXTRACT_SECRET, &saved_secret);
1408 if (r < 0)
1409 return r;
1410
1411 secret = saved_secret;
1412 }
1413
1414 r = manager_verify_user_record(h->manager, hr);
1415 switch (r) {
1416
1417 case USER_RECORD_UNSIGNED:
1418 if (h->signed_locally <= 0) /* If the existing record is not owned by us, don't accept an
1419 * unsigned new record. i.e. only implicitly sign new records
1420 * that where previously signed by us too. */
1421 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);
1422
1423 /* The updated record is not signed, then do so now */
1424 r = manager_sign_user_record(h->manager, hr, &signed_hr, error);
1425 if (r < 0)
1426 return r;
1427
1428 hr = signed_hr;
1429 break;
1430
1431 case USER_RECORD_SIGNED_EXCLUSIVE:
1432 case USER_RECORD_SIGNED:
1433 case USER_RECORD_FOREIGN:
1434 /* Has already been signed. Great! */
1435 break;
1436
1437 case -ENOKEY:
1438 default:
1439 return r;
1440 }
1441
1442 r = user_record_extend_with_binding(hr, h->record, USER_RECORD_LOAD_MASK_SECRET, &new_hr);
1443 if (r < 0)
1444 return r;
1445
1446 if (c == 0) {
1447 /* different payload but same lastChangeUSec field? That's not cool! */
1448
1449 r = user_record_masked_equal(new_hr, h->record, USER_RECORD_REGULAR|USER_RECORD_PRIVILEGED|USER_RECORD_PER_MACHINE);
1450 if (r < 0)
1451 return r;
1452 if (r == 0)
1453 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_MISMATCH, "Home record different but timestamp remained the same, refusing.");
1454 }
1455
1456 r = home_start_work(h, verb, new_hr, secret);
1457 if (r < 0)
1458 return r;
1459
1460 return 0;
1461}
1462
1463int home_update(Home *h, UserRecord *hr, sd_bus_error *error) {
1464 HomeState state;
1465 int r;
1466
1467 assert(h);
1468 assert(hr);
1469
1470 state = home_get_state(h);
1471 switch (state) {
1472 case HOME_UNFIXATED:
1473 return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
1474 case HOME_ABSENT:
1475 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
1476 case HOME_LOCKED:
1477 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1478 case HOME_INACTIVE:
9be99f81 1479 case HOME_DIRTY:
70a5db58
LP
1480 case HOME_ACTIVE:
1481 break;
1482 default:
1483 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1484 }
1485
1486 r = home_ratelimit(h, error);
1487 if (r < 0)
1488 return r;
1489
1490 r = home_update_internal(h, "update", hr, NULL, error);
1491 if (r < 0)
1492 return r;
1493
1494 home_set_state(h, state == HOME_ACTIVE ? HOME_UPDATING_WHILE_ACTIVE : HOME_UPDATING);
1495 return 0;
1496}
1497
1498int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *error) {
1499 _cleanup_(user_record_unrefp) UserRecord *c = NULL;
1500 HomeState state;
1501 int r;
1502
1503 assert(h);
1504
1505 state = home_get_state(h);
1506 switch (state) {
1507 case HOME_UNFIXATED:
1508 return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
1509 case HOME_ABSENT:
1510 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
1511 case HOME_LOCKED:
1512 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1513 case HOME_INACTIVE:
9be99f81 1514 case HOME_DIRTY:
70a5db58
LP
1515 case HOME_ACTIVE:
1516 break;
1517 default:
1518 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1519 }
1520
1521 r = home_ratelimit(h, error);
1522 if (r < 0)
1523 return r;
1524
1525 if (disk_size == UINT64_MAX || disk_size == h->record->disk_size) {
1526 if (h->record->disk_size == UINT64_MAX)
80ace4f2 1527 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "No disk size to resize to specified.");
70a5db58
LP
1528
1529 c = user_record_ref(h->record); /* Shortcut if size is unspecified or matches the record */
1530 } else {
1531 _cleanup_(user_record_unrefp) UserRecord *signed_c = NULL;
1532
1533 if (h->signed_locally <= 0) /* Don't allow changing of records not signed only by us */
1534 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);
1535
1536 r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET, &c);
1537 if (r < 0)
1538 return r;
1539
1540 r = user_record_set_disk_size(c, disk_size);
1541 if (r == -ERANGE)
1542 return sd_bus_error_setf(error, BUS_ERROR_BAD_HOME_SIZE, "Requested size for home %s out of acceptable range.", h->user_name);
1543 if (r < 0)
1544 return r;
1545
1546 r = user_record_update_last_changed(c, false);
1547 if (r == -ECHRNG)
1548 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);
1549 if (r < 0)
1550 return r;
1551
1552 r = manager_sign_user_record(h->manager, c, &signed_c, error);
1553 if (r < 0)
1554 return r;
1555
1556 user_record_unref(c);
1557 c = TAKE_PTR(signed_c);
1558 }
1559
1560 r = home_update_internal(h, "resize", c, secret, error);
1561 if (r < 0)
1562 return r;
1563
1564 home_set_state(h, state == HOME_ACTIVE ? HOME_RESIZING_WHILE_ACTIVE : HOME_RESIZING);
1565 return 0;
1566}
1567
1568static int home_may_change_password(
1569 Home *h,
1570 sd_bus_error *error) {
1571
1572 int r;
1573
1574 assert(h);
1575
1576 r = user_record_test_password_change_required(h->record);
1577 if (IN_SET(r, -EKEYREVOKED, -EOWNERDEAD, -EKEYEXPIRED))
86b52a39 1578 return 0; /* expired in some form, but changing is allowed */
70a5db58
LP
1579 if (IN_SET(r, -EKEYREJECTED, -EROFS))
1580 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);
1581 if (r < 0)
1582 return log_error_errno(r, "Failed to test password expiry: %m");
1583
1584 return 0; /* not expired */
1585}
1586
1587int home_passwd(Home *h,
1588 UserRecord *new_secret,
1589 UserRecord *old_secret,
1590 sd_bus_error *error) {
1591
1592 _cleanup_(user_record_unrefp) UserRecord *c = NULL, *merged_secret = NULL, *signed_c = NULL;
1593 HomeState state;
1594 int r;
1595
1596 assert(h);
1597
1598 if (h->signed_locally <= 0) /* Don't allow changing of records not signed only by us */
1599 return sd_bus_error_setf(error, BUS_ERROR_HOME_RECORD_SIGNED, "Home %s is signed and cannot be modified locally.", h->user_name);
1600
1601 state = home_get_state(h);
1602 switch (state) {
1603 case HOME_UNFIXATED:
1604 return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s has not been fixated yet.", h->user_name);
1605 case HOME_ABSENT:
1606 return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
1607 case HOME_LOCKED:
1608 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1609 case HOME_INACTIVE:
9be99f81 1610 case HOME_DIRTY:
70a5db58
LP
1611 case HOME_ACTIVE:
1612 break;
1613 default:
1614 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1615 }
1616
1617 r = home_ratelimit(h, error);
1618 if (r < 0)
1619 return r;
1620
1621 r = home_may_change_password(h, error);
1622 if (r < 0)
1623 return r;
1624
1625 r = user_record_clone(h->record, USER_RECORD_LOAD_REFUSE_SECRET, &c);
1626 if (r < 0)
1627 return r;
1628
1629 merged_secret = user_record_new();
1630 if (!merged_secret)
1631 return -ENOMEM;
1632
1633 r = user_record_merge_secret(merged_secret, old_secret);
1634 if (r < 0)
1635 return r;
1636
1637 r = user_record_merge_secret(merged_secret, new_secret);
1638 if (r < 0)
1639 return r;
1640
1641 if (!strv_isempty(new_secret->password)) {
1642 /* Update the password only if one is specified, otherwise let's just reuse the old password
1643 * data. This is useful as a way to propagate updated user records into the LUKS backends
1644 * properly. */
1645
1646 r = user_record_make_hashed_password(c, new_secret->password, /* extend = */ false);
1647 if (r < 0)
1648 return r;
1649
1650 r = user_record_set_password_change_now(c, -1 /* remove */);
1651 if (r < 0)
1652 return r;
1653 }
1654
1655 r = user_record_update_last_changed(c, true);
1656 if (r == -ECHRNG)
1657 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);
1658 if (r < 0)
1659 return r;
1660
1661 r = manager_sign_user_record(h->manager, c, &signed_c, error);
1662 if (r < 0)
1663 return r;
1664
1665 if (c->enforce_password_policy == false)
1666 log_debug("Password quality check turned off for account, skipping.");
1667 else {
679badd7 1668 r = user_record_quality_check_password(c, merged_secret, error);
70a5db58
LP
1669 if (r < 0)
1670 return r;
1671 }
1672
1673 r = home_update_internal(h, "passwd", signed_c, merged_secret, error);
1674 if (r < 0)
1675 return r;
1676
1677 home_set_state(h, state == HOME_ACTIVE ? HOME_PASSWD_WHILE_ACTIVE : HOME_PASSWD);
1678 return 0;
1679}
1680
1681int home_unregister(Home *h, sd_bus_error *error) {
1682 int r;
1683
1684 assert(h);
1685
1686 switch (home_get_state(h)) {
1687 case HOME_UNFIXATED:
1688 return sd_bus_error_setf(error, BUS_ERROR_HOME_UNFIXATED, "Home %s is not registered.", h->user_name);
1689 case HOME_LOCKED:
1690 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
1691 case HOME_ABSENT:
1692 case HOME_INACTIVE:
9be99f81 1693 case HOME_DIRTY:
70a5db58
LP
1694 break;
1695 case HOME_ACTIVE:
1696 default:
1697 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);
1698 }
1699
1700 r = home_unlink_record(h);
1701 if (r < 0)
1702 return r;
1703
1704 /* And destroy the whole entry. The caller needs to be prepared for that. */
1705 h = home_free(h);
1706 return 1;
1707}
1708
1709int home_lock(Home *h, sd_bus_error *error) {
1710 int r;
1711
1712 assert(h);
1713
1714 switch (home_get_state(h)) {
1715 case HOME_UNFIXATED:
1716 case HOME_ABSENT:
1717 case HOME_INACTIVE:
9be99f81 1718 case HOME_DIRTY:
70a5db58
LP
1719 return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s is not active.", h->user_name);
1720 case HOME_LOCKED:
1721 return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is already locked.", h->user_name);
1722 case HOME_ACTIVE:
1723 break;
1724 default:
1725 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1726 }
1727
1728 r = home_start_work(h, "lock", h->record, NULL);
1729 if (r < 0)
1730 return r;
1731
1732 home_set_state(h, HOME_LOCKING);
1733 return 0;
1734}
1735
1736static int home_unlock_internal(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) {
1737 int r;
1738
1739 assert(h);
1740 assert(IN_SET(for_state, HOME_UNLOCKING, HOME_UNLOCKING_FOR_ACQUIRE));
1741
1742 r = home_start_work(h, "unlock", h->record, secret);
1743 if (r < 0)
1744 return r;
1745
1746 home_set_state(h, for_state);
1747 return 0;
1748}
1749
1750int home_unlock(Home *h, UserRecord *secret, sd_bus_error *error) {
1751 int r;
1752 assert(h);
1753
1754 r = home_ratelimit(h, error);
1755 if (r < 0)
1756 return r;
1757
1758 switch (home_get_state(h)) {
1759 case HOME_UNFIXATED:
1760 case HOME_ABSENT:
1761 case HOME_INACTIVE:
1762 case HOME_ACTIVE:
9be99f81 1763 case HOME_DIRTY:
70a5db58
LP
1764 return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_LOCKED, "Home %s is not locked.", h->user_name);
1765 case HOME_LOCKED:
1766 break;
1767 default:
1768 return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
1769 }
1770
1771 return home_unlock_internal(h, secret, HOME_UNLOCKING, error);
1772}
1773
1774HomeState home_get_state(Home *h) {
9be99f81 1775 int r;
70a5db58
LP
1776 assert(h);
1777
1778 /* When the state field is initialized, it counts. */
1779 if (h->state >= 0)
1780 return h->state;
1781
1782 /* Otherwise, let's see if the home directory is mounted. If so, we assume for sure the home
1783 * directory is active */
1784 if (user_record_test_home_directory(h->record) == USER_TEST_MOUNTED)
1785 return HOME_ACTIVE;
1786
1787 /* And if we see the image being gone, we report this as absent */
9be99f81
LP
1788 r = user_record_test_image_path(h->record);
1789 if (r == USER_TEST_ABSENT)
70a5db58 1790 return HOME_ABSENT;
9be99f81
LP
1791 if (r == USER_TEST_DIRTY)
1792 return HOME_DIRTY;
70a5db58
LP
1793
1794 /* And for all other cases we return "inactive". */
1795 return HOME_INACTIVE;
1796}
1797
1798void home_process_notify(Home *h, char **l) {
1799 const char *e;
1800 int error;
1801 int r;
1802
1803 assert(h);
1804
1805 e = strv_env_get(l, "ERRNO");
1806 if (!e) {
1807 log_debug("Got notify message lacking ERRNO= field, ignoring.");
1808 return;
1809 }
1810
1811 r = safe_atoi(e, &error);
1812 if (r < 0) {
162392b7 1813 log_debug_errno(r, "Failed to parse received error number, ignoring: %s", e);
70a5db58
LP
1814 return;
1815 }
1816 if (error <= 0) {
1817 log_debug("Error number is out of range: %i", error);
1818 return;
1819 }
1820
1821 h->worker_error_code = error;
1822}
1823
1824int home_killall(Home *h) {
1825 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1826 _cleanup_free_ char *unit = NULL;
1827 int r;
1828
1829 assert(h);
1830
1831 if (!uid_is_valid(h->uid))
1832 return 0;
1833
1834 assert(h->uid > 0); /* We never should be UID 0 */
1835
1836 /* Let's kill everything matching the specified UID */
1837 r = safe_fork("(sd-killer)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG, NULL);
1838 if (r < 0)
1839 return r;
1840 if (r == 0) {
1841 gid_t gid;
1842
1843 /* Child */
1844
1845 gid = user_record_gid(h->record);
1846 if (setresgid(gid, gid, gid) < 0) {
1847 log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid);
1848 _exit(EXIT_FAILURE);
1849 }
1850
1851 if (setgroups(0, NULL) < 0) {
1852 log_error_errno(errno, "Failed to reset auxiliary groups list: %m");
1853 _exit(EXIT_FAILURE);
1854 }
1855
1856 if (setresuid(h->uid, h->uid, h->uid) < 0) {
1857 log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", h->uid);
1858 _exit(EXIT_FAILURE);
1859 }
1860
1861 if (kill(-1, SIGKILL) < 0) {
1862 log_error_errno(errno, "Failed to kill all processes of UID " UID_FMT ": %m", h->uid);
1863 _exit(EXIT_FAILURE);
1864 }
1865
1866 _exit(EXIT_SUCCESS);
1867 }
1868
1869 /* Let's also kill everything in the user's slice */
1870 if (asprintf(&unit, "user-" UID_FMT ".slice", h->uid) < 0)
1871 return log_oom();
1872
1873 r = sd_bus_call_method(
1874 h->manager->bus,
1875 "org.freedesktop.systemd1",
1876 "/org/freedesktop/systemd1",
1877 "org.freedesktop.systemd1.Manager",
1878 "KillUnit",
1879 &error,
1880 NULL,
1881 "ssi", unit, "all", SIGKILL);
1882 if (r < 0)
1883 log_full_errno(sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ? LOG_DEBUG : LOG_WARNING,
1884 r, "Failed to kill login processes of user, ignoring: %s", bus_error_message(&error, r));
1885
1886 return 1;
1887}
1888
1889static int home_get_disk_status_luks(
1890 Home *h,
1891 HomeState state,
1892 uint64_t *ret_disk_size,
1893 uint64_t *ret_disk_usage,
1894 uint64_t *ret_disk_free,
1895 uint64_t *ret_disk_ceiling,
1896 uint64_t *ret_disk_floor) {
1897
1898 uint64_t disk_size = UINT64_MAX, disk_usage = UINT64_MAX, disk_free = UINT64_MAX,
1899 disk_ceiling = UINT64_MAX, disk_floor = UINT64_MAX,
1900 stat_used = UINT64_MAX, fs_size = UINT64_MAX, header_size = 0;
1901
1902 struct statfs sfs;
1903 const char *hd;
1904 int r;
1905
1906 assert(h);
1907 assert(ret_disk_size);
1908 assert(ret_disk_usage);
1909 assert(ret_disk_free);
1910 assert(ret_disk_ceiling);
1911
1912 if (state != HOME_ABSENT) {
1913 const char *ip;
1914
1915 ip = user_record_image_path(h->record);
1916 if (ip) {
1917 struct stat st;
1918
1919 if (stat(ip, &st) < 0)
1920 log_debug_errno(errno, "Failed to stat() %s, ignoring: %m", ip);
1921 else if (S_ISREG(st.st_mode)) {
1922 _cleanup_free_ char *parent = NULL;
1923
1924 disk_size = st.st_size;
1925 stat_used = st.st_blocks * 512;
1926
1927 parent = dirname_malloc(ip);
1928 if (!parent)
1929 return log_oom();
1930
1931 if (statfs(parent, &sfs) < 0)
1932 log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", parent);
1933 else
1934 disk_ceiling = stat_used + sfs.f_bsize * sfs.f_bavail;
1935
1936 } else if (S_ISBLK(st.st_mode)) {
1937 _cleanup_free_ char *szbuf = NULL;
1938 char p[SYS_BLOCK_PATH_MAX("/size")];
1939
1940 /* Let's read the size off sysfs, so that we don't have to open the device */
1941 xsprintf_sys_block_path(p, "/size", st.st_rdev);
1942 r = read_one_line_file(p, &szbuf);
1943 if (r < 0)
1944 log_debug_errno(r, "Failed to read %s, ignoring: %m", p);
1945 else {
1946 uint64_t sz;
1947
1948 r = safe_atou64(szbuf, &sz);
1949 if (r < 0)
1950 log_debug_errno(r, "Failed to parse %s, ignoring: %s", p, szbuf);
1951 else
1952 disk_size = sz * 512;
1953 }
1954 } else
1955 log_debug("Image path is not a block device or regular file, not able to acquire size.");
1956 }
1957 }
1958
1959 if (!HOME_STATE_IS_ACTIVE(state))
1960 goto finish;
1961
1962 hd = user_record_home_directory(h->record);
1963 if (!hd)
1964 goto finish;
1965
1966 if (statfs(hd, &sfs) < 0) {
80ace4f2 1967 log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", hd);
70a5db58
LP
1968 goto finish;
1969 }
1970
1971 disk_free = sfs.f_bsize * sfs.f_bavail;
1972 fs_size = sfs.f_bsize * sfs.f_blocks;
1973 if (disk_size != UINT64_MAX && disk_size > fs_size)
1974 header_size = disk_size - fs_size;
1975
1976 /* We take a perspective from the user here (as opposed to from the host): the used disk space is the
1977 * difference from the limit and what's free. This makes a difference if sparse mode is not used: in
1978 * that case the image is pre-allocated and thus appears all used from the host PoV but is not used
1979 * up at all yet from the user's PoV.
1980 *
1981 * That said, we use use the stat() reported loopback file size as upper boundary: our footprint can
1982 * never be larger than what we take up on the lowest layers. */
1983
1984 if (disk_size != UINT64_MAX && disk_size > disk_free) {
1985 disk_usage = disk_size - disk_free;
1986
1987 if (stat_used != UINT64_MAX && disk_usage > stat_used)
1988 disk_usage = stat_used;
1989 } else
1990 disk_usage = stat_used;
1991
1992 /* If we have the magic, determine floor preferably by magic */
1993 disk_floor = minimal_size_by_fs_magic(sfs.f_type) + header_size;
1994
1995finish:
1996 /* If we don't know the magic, go by file system name */
1997 if (disk_floor == UINT64_MAX)
1998 disk_floor = minimal_size_by_fs_name(user_record_file_system_type(h->record));
1999
2000 *ret_disk_size = disk_size;
2001 *ret_disk_usage = disk_usage;
2002 *ret_disk_free = disk_free;
2003 *ret_disk_ceiling = disk_ceiling;
2004 *ret_disk_floor = disk_floor;
2005
2006 return 0;
2007}
2008
2009static int home_get_disk_status_directory(
2010 Home *h,
2011 HomeState state,
2012 uint64_t *ret_disk_size,
2013 uint64_t *ret_disk_usage,
2014 uint64_t *ret_disk_free,
2015 uint64_t *ret_disk_ceiling,
2016 uint64_t *ret_disk_floor) {
2017
2018 uint64_t disk_size = UINT64_MAX, disk_usage = UINT64_MAX, disk_free = UINT64_MAX,
2019 disk_ceiling = UINT64_MAX, disk_floor = UINT64_MAX;
2020 struct statfs sfs;
2021 struct dqblk req;
2022 const char *path = NULL;
2023 int r;
2024
2025 assert(ret_disk_size);
2026 assert(ret_disk_usage);
2027 assert(ret_disk_free);
2028 assert(ret_disk_ceiling);
2029 assert(ret_disk_floor);
2030
2031 if (HOME_STATE_IS_ACTIVE(state))
2032 path = user_record_home_directory(h->record);
2033
2034 if (!path) {
2035 if (state == HOME_ABSENT)
2036 goto finish;
2037
2038 path = user_record_image_path(h->record);
2039 }
2040
2041 if (!path)
2042 goto finish;
2043
2044 if (statfs(path, &sfs) < 0)
2045 log_debug_errno(errno, "Failed to statfs() %s, ignoring: %m", path);
2046 else {
2047 disk_free = sfs.f_bsize * sfs.f_bavail;
2048 disk_size = sfs.f_bsize * sfs.f_blocks;
2049
2050 /* We don't initialize disk_usage from statfs() data here, since the device is likely not used
2051 * by us alone, and disk_usage should only reflect our own use. */
2052 }
2053
2054 if (IN_SET(h->record->storage, USER_CLASSIC, USER_DIRECTORY, USER_SUBVOLUME)) {
2055
2056 r = btrfs_is_subvol(path);
2057 if (r < 0)
2058 log_debug_errno(r, "Failed to determine whether %s is a btrfs subvolume: %m", path);
2059 else if (r > 0) {
2060 BtrfsQuotaInfo qi;
2061
2062 r = btrfs_subvol_get_subtree_quota(path, 0, &qi);
2063 if (r < 0)
2064 log_debug_errno(r, "Failed to query btrfs subtree quota, ignoring: %m");
2065 else {
2066 disk_usage = qi.referenced;
2067
2068 if (disk_free != UINT64_MAX) {
2069 disk_ceiling = qi.referenced + disk_free;
2070
2071 if (disk_size != UINT64_MAX && disk_ceiling > disk_size)
2072 disk_ceiling = disk_size;
2073 }
2074
2075 if (qi.referenced_max != UINT64_MAX) {
2076 if (disk_size != UINT64_MAX)
2077 disk_size = MIN(qi.referenced_max, disk_size);
2078 else
2079 disk_size = qi.referenced_max;
2080 }
2081
2082 if (disk_size != UINT64_MAX) {
2083 if (disk_size > disk_usage)
2084 disk_free = disk_size - disk_usage;
2085 else
2086 disk_free = 0;
2087 }
2088 }
2089
2090 goto finish;
2091 }
2092 }
2093
2094 if (IN_SET(h->record->storage, USER_CLASSIC, USER_DIRECTORY, USER_FSCRYPT)) {
2095 r = quotactl_path(QCMD_FIXED(Q_GETQUOTA, USRQUOTA), path, h->uid, &req);
2096 if (r < 0) {
2097 if (ERRNO_IS_NOT_SUPPORTED(r)) {
2098 log_debug_errno(r, "No UID quota support on %s.", path);
2099 goto finish;
2100 }
2101
2102 if (r != -ESRCH) {
2103 log_debug_errno(r, "Failed to query disk quota for UID " UID_FMT ": %m", h->uid);
2104 goto finish;
2105 }
2106
2107 disk_usage = 0; /* No record of this user? then nothing was used */
2108 } else {
2109 if (FLAGS_SET(req.dqb_valid, QIF_SPACE) && disk_free != UINT64_MAX) {
2110 disk_ceiling = req.dqb_curspace + disk_free;
2111
2112 if (disk_size != UINT64_MAX && disk_ceiling > disk_size)
2113 disk_ceiling = disk_size;
2114 }
2115
2116 if (FLAGS_SET(req.dqb_valid, QIF_BLIMITS)) {
2117 uint64_t q;
2118
2119 /* Take the minimum of the quota and the available disk space here */
2120 q = req.dqb_bhardlimit * QIF_DQBLKSIZE;
2121 if (disk_size != UINT64_MAX)
2122 disk_size = MIN(disk_size, q);
2123 else
2124 disk_size = q;
2125 }
2126 if (FLAGS_SET(req.dqb_valid, QIF_SPACE)) {
2127 disk_usage = req.dqb_curspace;
2128
2129 if (disk_size != UINT64_MAX) {
2130 if (disk_size > disk_usage)
2131 disk_free = disk_size - disk_usage;
2132 else
2133 disk_free = 0;
2134 }
2135 }
2136 }
2137 }
2138
2139finish:
2140 *ret_disk_size = disk_size;
2141 *ret_disk_usage = disk_usage;
2142 *ret_disk_free = disk_free;
2143 *ret_disk_ceiling = disk_ceiling;
2144 *ret_disk_floor = disk_floor;
2145
2146 return 0;
2147}
2148
2149int home_augment_status(
2150 Home *h,
2151 UserRecordLoadFlags flags,
2152 UserRecord **ret) {
2153
2154 uint64_t disk_size = UINT64_MAX, disk_usage = UINT64_MAX, disk_free = UINT64_MAX, disk_ceiling = UINT64_MAX, disk_floor = UINT64_MAX;
2155 _cleanup_(json_variant_unrefp) JsonVariant *j = NULL, *v = NULL, *m = NULL, *status = NULL;
2156 _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
2157 char ids[SD_ID128_STRING_MAX];
2158 HomeState state;
2159 sd_id128_t id;
2160 int r;
2161
2162 assert(h);
2163 assert(ret);
2164
2165 /* We are supposed to add this, this can't be on hence. */
2166 assert(!FLAGS_SET(flags, USER_RECORD_STRIP_STATUS));
2167
2168 r = sd_id128_get_machine(&id);
2169 if (r < 0)
2170 return r;
2171
2172 state = home_get_state(h);
2173
2174 switch (h->record->storage) {
2175
2176 case USER_LUKS:
2177 r = home_get_disk_status_luks(h, state, &disk_size, &disk_usage, &disk_free, &disk_ceiling, &disk_floor);
2178 if (r < 0)
2179 return r;
2180
2181 break;
2182
2183 case USER_CLASSIC:
2184 case USER_DIRECTORY:
2185 case USER_SUBVOLUME:
2186 case USER_FSCRYPT:
2187 case USER_CIFS:
2188 r = home_get_disk_status_directory(h, state, &disk_size, &disk_usage, &disk_free, &disk_ceiling, &disk_floor);
2189 if (r < 0)
2190 return r;
2191
2192 break;
2193
2194 default:
2195 ; /* unset */
2196 }
2197
2198 if (disk_floor == UINT64_MAX || (disk_usage != UINT64_MAX && disk_floor < disk_usage))
2199 disk_floor = disk_usage;
2200 if (disk_floor == UINT64_MAX || disk_floor < USER_DISK_SIZE_MIN)
2201 disk_floor = USER_DISK_SIZE_MIN;
2202 if (disk_ceiling == UINT64_MAX || disk_ceiling > USER_DISK_SIZE_MAX)
2203 disk_ceiling = USER_DISK_SIZE_MAX;
2204
2205 r = json_build(&status,
2206 JSON_BUILD_OBJECT(
2207 JSON_BUILD_PAIR("state", JSON_BUILD_STRING(home_state_to_string(state))),
2208 JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.Home")),
2209 JSON_BUILD_PAIR_CONDITION(disk_size != UINT64_MAX, "diskSize", JSON_BUILD_UNSIGNED(disk_size)),
2210 JSON_BUILD_PAIR_CONDITION(disk_usage != UINT64_MAX, "diskUsage", JSON_BUILD_UNSIGNED(disk_usage)),
2211 JSON_BUILD_PAIR_CONDITION(disk_free != UINT64_MAX, "diskFree", JSON_BUILD_UNSIGNED(disk_free)),
2212 JSON_BUILD_PAIR_CONDITION(disk_ceiling != UINT64_MAX, "diskCeiling", JSON_BUILD_UNSIGNED(disk_ceiling)),
2213 JSON_BUILD_PAIR_CONDITION(disk_floor != UINT64_MAX, "diskFloor", JSON_BUILD_UNSIGNED(disk_floor)),
2214 JSON_BUILD_PAIR_CONDITION(h->signed_locally >= 0, "signedLocally", JSON_BUILD_BOOLEAN(h->signed_locally))
2215 ));
2216 if (r < 0)
2217 return r;
2218
2219 j = json_variant_ref(h->record->json);
2220 v = json_variant_ref(json_variant_by_key(j, "status"));
2221 m = json_variant_ref(json_variant_by_key(v, sd_id128_to_string(id, ids)));
2222
2223 r = json_variant_filter(&m, STRV_MAKE("diskSize", "diskUsage", "diskFree", "diskCeiling", "diskFloor", "signedLocally"));
2224 if (r < 0)
2225 return r;
2226
2227 r = json_variant_merge(&m, status);
2228 if (r < 0)
2229 return r;
2230
2231 r = json_variant_set_field(&v, ids, m);
2232 if (r < 0)
2233 return r;
2234
2235 r = json_variant_set_field(&j, "status", v);
2236 if (r < 0)
2237 return r;
2238
2239 ur = user_record_new();
2240 if (!ur)
2241 return -ENOMEM;
2242
2243 r = user_record_load(ur, j, flags);
2244 if (r < 0)
2245 return r;
2246
2247 ur->incomplete =
2248 FLAGS_SET(h->record->mask, USER_RECORD_PRIVILEGED) &&
2249 !FLAGS_SET(ur->mask, USER_RECORD_PRIVILEGED);
2250
2251 *ret = TAKE_PTR(ur);
2252 return 0;
2253}
2254
2255static int on_home_ref_eof(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
2256 _cleanup_(operation_unrefp) Operation *o = NULL;
2257 Home *h = userdata;
2258
2259 assert(s);
2260 assert(h);
2261
2262 if (h->ref_event_source_please_suspend == s)
2263 h->ref_event_source_please_suspend = sd_event_source_disable_unref(h->ref_event_source_please_suspend);
2264
2265 if (h->ref_event_source_dont_suspend == s)
2266 h->ref_event_source_dont_suspend = sd_event_source_disable_unref(h->ref_event_source_dont_suspend);
2267
2268 if (h->ref_event_source_dont_suspend || h->ref_event_source_please_suspend)
2269 return 0;
2270
2271 log_info("Got notification that all sessions of user %s ended, deactivating automatically.", h->user_name);
2272
2273 o = operation_new(OPERATION_PIPE_EOF, NULL);
2274 if (!o) {
2275 log_oom();
2276 return 0;
2277 }
2278
2279 home_schedule_operation(h, o, NULL);
2280 return 0;
2281}
2282
2283int home_create_fifo(Home *h, bool please_suspend) {
2284 _cleanup_close_ int ret_fd = -1;
2285 sd_event_source **ss;
2286 const char *fn, *suffix;
2287 int r;
2288
2289 assert(h);
2290
2291 if (please_suspend) {
2292 suffix = ".please-suspend";
2293 ss = &h->ref_event_source_please_suspend;
2294 } else {
2295 suffix = ".dont-suspend";
2296 ss = &h->ref_event_source_dont_suspend;
2297 }
2298
2299 fn = strjoina("/run/systemd/home/", h->user_name, suffix);
2300
2301 if (!*ss) {
2302 _cleanup_close_ int ref_fd = -1;
2303
2304 (void) mkdir("/run/systemd/home/", 0755);
2305 if (mkfifo(fn, 0600) < 0 && errno != EEXIST)
2306 return log_error_errno(errno, "Failed to create FIFO %s: %m", fn);
2307
2308 ref_fd = open(fn, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
2309 if (ref_fd < 0)
2310 return log_error_errno(errno, "Failed to open FIFO %s for reading: %m", fn);
2311
2312 r = sd_event_add_io(h->manager->event, ss, ref_fd, 0, on_home_ref_eof, h);
2313 if (r < 0)
2314 return log_error_errno(r, "Failed to allocate reference FIFO event source: %m");
2315
2316 (void) sd_event_source_set_description(*ss, "acquire-ref");
2317
2318 r = sd_event_source_set_priority(*ss, SD_EVENT_PRIORITY_IDLE-1);
2319 if (r < 0)
2320 return r;
2321
2322 r = sd_event_source_set_io_fd_own(*ss, true);
2323 if (r < 0)
2324 return log_error_errno(r, "Failed to pass ownership of FIFO event fd to event source: %m");
2325
2326 TAKE_FD(ref_fd);
2327 }
2328
2329 ret_fd = open(fn, O_WRONLY|O_CLOEXEC|O_NONBLOCK);
2330 if (ret_fd < 0)
2331 return log_error_errno(errno, "Failed to open FIFO %s for writing: %m", fn);
2332
2333 return TAKE_FD(ret_fd);
2334}
2335
2336static int home_dispatch_acquire(Home *h, Operation *o) {
2337 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2338 int (*call)(Home *h, UserRecord *secret, HomeState for_state, sd_bus_error *error) = NULL;
2339 HomeState for_state;
2340 int r;
2341
2342 assert(h);
2343 assert(o);
2344 assert(o->type == OPERATION_ACQUIRE);
2345
2346 switch (home_get_state(h)) {
2347
2348 case HOME_UNFIXATED:
2349 for_state = HOME_FIXATING_FOR_ACQUIRE;
2350 call = home_fixate_internal;
2351 break;
2352
2353 case HOME_ABSENT:
2354 r = sd_bus_error_setf(&error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
2355 break;
2356
2357 case HOME_INACTIVE:
9be99f81 2358 case HOME_DIRTY:
70a5db58
LP
2359 for_state = HOME_ACTIVATING_FOR_ACQUIRE;
2360 call = home_activate_internal;
2361 break;
2362
2363 case HOME_ACTIVE:
2364 for_state = HOME_AUTHENTICATING_FOR_ACQUIRE;
2365 call = home_authenticate_internal;
2366 break;
2367
2368 case HOME_LOCKED:
2369 for_state = HOME_UNLOCKING_FOR_ACQUIRE;
2370 call = home_unlock_internal;
2371 break;
2372
2373 default:
2374 /* All other cases means we are currently executing an operation, which means the job remains
2375 * pending. */
2376 return 0;
2377 }
2378
2379 assert(!h->current_operation);
2380
2381 if (call) {
2382 r = home_ratelimit(h, &error);
2383 if (r >= 0)
2384 r = call(h, o->secret, for_state, &error);
2385 }
2386
2387 if (r != 0) /* failure or completed */
2388 operation_result(o, r, &error);
2389 else /* ongoing */
2390 h->current_operation = operation_ref(o);
2391
2392 return 1;
2393}
2394
2395static int home_dispatch_release(Home *h, Operation *o) {
2396 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2397 int r;
2398
2399 assert(h);
2400 assert(o);
2401 assert(o->type == OPERATION_RELEASE);
2402
2403 if (h->ref_event_source_dont_suspend || h->ref_event_source_please_suspend)
2404 /* If there's now a reference again, then let's abort the release attempt */
2405 r = sd_bus_error_setf(&error, BUS_ERROR_HOME_BUSY, "Home %s is currently referenced.", h->user_name);
2406 else {
2407 switch (home_get_state(h)) {
2408
2409 case HOME_UNFIXATED:
2410 case HOME_ABSENT:
2411 case HOME_INACTIVE:
9be99f81 2412 case HOME_DIRTY:
a60416f3 2413 r = 1; /* done */
70a5db58
LP
2414 break;
2415
2416 case HOME_LOCKED:
2417 r = sd_bus_error_setf(&error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
2418 break;
2419
2420 case HOME_ACTIVE:
2421 r = home_deactivate_internal(h, false, &error);
2422 break;
2423
2424 default:
2425 /* All other cases means we are currently executing an operation, which means the job remains
2426 * pending. */
2427 return 0;
2428 }
2429 }
2430
2431 assert(!h->current_operation);
2432
a60416f3 2433 if (r != 0) /* failure or completed */
70a5db58
LP
2434 operation_result(o, r, &error);
2435 else /* ongoing */
2436 h->current_operation = operation_ref(o);
2437
2438 return 1;
2439}
2440
2441static int home_dispatch_lock_all(Home *h, Operation *o) {
2442 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2443 int r;
2444
2445 assert(h);
2446 assert(o);
2447 assert(o->type == OPERATION_LOCK_ALL);
2448
2449 switch (home_get_state(h)) {
2450
2451 case HOME_UNFIXATED:
2452 case HOME_ABSENT:
2453 case HOME_INACTIVE:
9be99f81 2454 case HOME_DIRTY:
70a5db58 2455 log_info("Home %s is not active, no locking necessary.", h->user_name);
a60416f3 2456 r = 1; /* done */
70a5db58
LP
2457 break;
2458
2459 case HOME_LOCKED:
2460 log_info("Home %s is already locked.", h->user_name);
a60416f3 2461 r = 1; /* done */
70a5db58
LP
2462 break;
2463
2464 case HOME_ACTIVE:
2465 log_info("Locking home %s.", h->user_name);
2466 r = home_lock(h, &error);
2467 break;
2468
2469 default:
2470 /* All other cases means we are currently executing an operation, which means the job remains
2471 * pending. */
2472 return 0;
2473 }
2474
2475 assert(!h->current_operation);
2476
2477 if (r != 0) /* failure or completed */
2478 operation_result(o, r, &error);
2479 else /* ongoing */
2480 h->current_operation = operation_ref(o);
2481
2482 return 1;
2483}
2484
2485static int home_dispatch_pipe_eof(Home *h, Operation *o) {
2486 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2487 int r;
2488
2489 assert(h);
2490 assert(o);
2491 assert(o->type == OPERATION_PIPE_EOF);
2492
2493 if (h->ref_event_source_please_suspend || h->ref_event_source_dont_suspend)
2494 return 1; /* Hmm, there's a reference again, let's cancel this */
2495
2496 switch (home_get_state(h)) {
2497
2498 case HOME_UNFIXATED:
2499 case HOME_ABSENT:
2500 case HOME_INACTIVE:
9be99f81 2501 case HOME_DIRTY:
70a5db58
LP
2502 log_info("Home %s already deactivated, no automatic deactivation needed.", h->user_name);
2503 break;
2504
2505 case HOME_DEACTIVATING:
2506 log_info("Home %s is already being deactivated, automatic deactivated unnecessary.", h->user_name);
2507 break;
2508
2509 case HOME_ACTIVE:
2510 r = home_deactivate_internal(h, false, &error);
2511 if (r < 0)
2512 log_warning_errno(r, "Failed to deactivate %s, ignoring: %s", h->user_name, bus_error_message(&error, r));
2513 break;
2514
2515 case HOME_LOCKED:
2516 default:
2517 /* If the device is locked or any operation is being executed, let's leave this pending */
2518 return 0;
2519 }
2520
2521 /* Note that we don't call operation_fail() or operation_success() here, because this kind of
2522 * operation has no message associated with it, and thus there's no need to propagate success. */
2523
2524 assert(!o->message);
2525 return 1;
2526}
2527
2528static int home_dispatch_deactivate_force(Home *h, Operation *o) {
2529 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
2530 int r;
2531
2532 assert(h);
2533 assert(o);
2534 assert(o->type == OPERATION_DEACTIVATE_FORCE);
2535
2536 switch (home_get_state(h)) {
2537
2538 case HOME_UNFIXATED:
2539 case HOME_ABSENT:
2540 case HOME_INACTIVE:
9be99f81 2541 case HOME_DIRTY:
70a5db58
LP
2542 log_debug("Home %s already deactivated, no forced deactivation due to unplug needed.", h->user_name);
2543 break;
2544
2545 case HOME_DEACTIVATING:
2546 log_debug("Home %s is already being deactivated, forced deactivation due to unplug unnecessary.", h->user_name);
2547 break;
2548
2549 case HOME_ACTIVE:
2550 case HOME_LOCKED:
2551 r = home_deactivate_internal(h, true, &error);
2552 if (r < 0)
2553 log_warning_errno(r, "Failed to forcibly deactivate %s, ignoring: %s", h->user_name, bus_error_message(&error, r));
2554 break;
2555
2556 default:
2557 /* If any operation is being executed, let's leave this pending */
2558 return 0;
2559 }
2560
2561 /* Note that we don't call operation_fail() or operation_success() here, because this kind of
2562 * operation has no message associated with it, and thus there's no need to propagate success. */
2563
2564 assert(!o->message);
2565 return 1;
2566}
2567
2568static int on_pending(sd_event_source *s, void *userdata) {
2569 Home *h = userdata;
2570 Operation *o;
2571 int r;
2572
2573 assert(s);
2574 assert(h);
2575
2576 o = ordered_set_first(h->pending_operations);
2577 if (o) {
2578 static int (* const operation_table[_OPERATION_MAX])(Home *h, Operation *o) = {
2579 [OPERATION_ACQUIRE] = home_dispatch_acquire,
2580 [OPERATION_RELEASE] = home_dispatch_release,
2581 [OPERATION_LOCK_ALL] = home_dispatch_lock_all,
2582 [OPERATION_PIPE_EOF] = home_dispatch_pipe_eof,
2583 [OPERATION_DEACTIVATE_FORCE] = home_dispatch_deactivate_force,
2584 };
2585
2586 assert(operation_table[o->type]);
2587 r = operation_table[o->type](h, o);
2588 if (r != 0) {
2589 /* The operation completed, let's remove it from the pending list, and exit while
2590 * leaving the event source enabled as it is. */
2591 assert_se(ordered_set_remove(h->pending_operations, o) == o);
2592 operation_unref(o);
2593 return 0;
2594 }
2595 }
2596
2597 /* Nothing to do anymore, let's turn off this event source */
2598 r = sd_event_source_set_enabled(s, SD_EVENT_OFF);
2599 if (r < 0)
2600 return log_error_errno(r, "Failed to disable event source: %m");
2601
2602 return 0;
2603}
2604
2605int home_schedule_operation(Home *h, Operation *o, sd_bus_error *error) {
2606 int r;
2607
2608 assert(h);
2609
2610 if (o) {
2611 if (ordered_set_size(h->pending_operations) >= PENDING_OPERATIONS_MAX)
2612 return sd_bus_error_setf(error, BUS_ERROR_TOO_MANY_OPERATIONS, "Too many client operations requested");
2613
2614 r = ordered_set_ensure_allocated(&h->pending_operations, &operation_hash_ops);
2615 if (r < 0)
2616 return r;
2617
2618 r = ordered_set_put(h->pending_operations, o);
2619 if (r < 0)
2620 return r;
2621
2622 operation_ref(o);
2623 }
2624
2625 if (!h->pending_event_source) {
2626 r = sd_event_add_defer(h->manager->event, &h->pending_event_source, on_pending, h);
2627 if (r < 0)
2628 return log_error_errno(r, "Failed to allocate pending defer event source: %m");
2629
2630 (void) sd_event_source_set_description(h->pending_event_source, "pending");
2631
2632 r = sd_event_source_set_priority(h->pending_event_source, SD_EVENT_PRIORITY_IDLE);
2633 if (r < 0)
2634 return r;
2635 }
2636
2637 r = sd_event_source_set_enabled(h->pending_event_source, SD_EVENT_ON);
2638 if (r < 0)
2639 return log_error_errno(r, "Failed to trigger pending event source: %m");
2640
2641 return 0;
2642}
2643
2644static int home_get_image_path_seat(Home *h, char **ret) {
2645 _cleanup_(sd_device_unrefp) sd_device *d = NULL;
2646 _cleanup_free_ char *c = NULL;
2647 const char *ip, *seat;
2648 struct stat st;
2649 int r;
2650
2651 assert(h);
2652
2653 if (user_record_storage(h->record) != USER_LUKS)
2654 return -ENXIO;
2655
2656 ip = user_record_image_path(h->record);
2657 if (!ip)
2658 return -ENXIO;
2659
2660 if (!path_startswith(ip, "/dev/"))
2661 return -ENXIO;
2662
2663 if (stat(ip, &st) < 0)
2664 return -errno;
2665
2666 if (!S_ISBLK(st.st_mode))
2667 return -ENOTBLK;
2668
2669 r = sd_device_new_from_devnum(&d, 'b', st.st_rdev);
2670 if (r < 0)
2671 return r;
2672
2673 r = sd_device_get_property_value(d, "ID_SEAT", &seat);
2674 if (r == -ENOENT) /* no property means seat0 */
2675 seat = "seat0";
2676 else if (r < 0)
2677 return r;
2678
2679 c = strdup(seat);
2680 if (!c)
2681 return -ENOMEM;
2682
2683 *ret = TAKE_PTR(c);
2684 return 0;
2685}
2686
2687int home_auto_login(Home *h, char ***ret_seats) {
2688 _cleanup_free_ char *seat = NULL, *seat2 = NULL;
2689
2690 assert(h);
2691 assert(ret_seats);
2692
2693 (void) home_get_image_path_seat(h, &seat);
2694
2695 if (h->record->auto_login > 0 && !streq_ptr(seat, "seat0")) {
2696 /* For now, when the auto-login boolean is set for a user, let's make it mean
2697 * "seat0". Eventually we can extend the concept and allow configuration of any kind of seat,
2698 * but let's keep simple initially, most likely the feature is interesting on single-user
2699 * systems anyway, only.
2700 *
2701 * We filter out users marked for auto-login in we know for sure their home directory is
2702 * absent. */
2703
2704 if (user_record_test_image_path(h->record) != USER_TEST_ABSENT) {
2705 seat2 = strdup("seat0");
2706 if (!seat2)
2707 return -ENOMEM;
2708 }
2709 }
2710
2711 if (seat || seat2) {
2712 _cleanup_strv_free_ char **list = NULL;
2713 size_t i = 0;
2714
2715 list = new(char*, 3);
2716 if (!list)
2717 return -ENOMEM;
2718
2719 if (seat)
2720 list[i++] = TAKE_PTR(seat);
2721 if (seat2)
2722 list[i++] = TAKE_PTR(seat2);
2723
2724 list[i] = NULL;
2725 *ret_seats = TAKE_PTR(list);
2726 return 1;
2727 }
2728
2729 *ret_seats = NULL;
2730 return 0;
2731}
2732
2733int home_set_current_message(Home *h, sd_bus_message *m) {
2734 assert(h);
2735
2736 if (!m)
2737 return 0;
2738
2739 if (h->current_operation)
2740 return -EBUSY;
2741
2742 h->current_operation = operation_new(OPERATION_IMMEDIATE, m);
2743 if (!h->current_operation)
2744 return -ENOMEM;
2745
2746 return 1;
2747}
2748
9796a9fb
LP
2749int home_wait_for_worker(Home *h) {
2750 assert(h);
2751
2752 if (h->worker_pid <= 0)
2753 return 0;
2754
2755 log_info("Worker process for home %s is still running while exiting. Waiting for it to finish.", h->user_name);
2756 (void) wait_for_terminate(h->worker_pid, NULL);
2757 (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h);
2758 h->worker_pid = 0;
2759 return 1;
2760}
2761
70a5db58
LP
2762static const char* const home_state_table[_HOME_STATE_MAX] = {
2763 [HOME_UNFIXATED] = "unfixated",
2764 [HOME_ABSENT] = "absent",
2765 [HOME_INACTIVE] = "inactive",
9be99f81 2766 [HOME_DIRTY] = "dirty",
70a5db58
LP
2767 [HOME_FIXATING] = "fixating",
2768 [HOME_FIXATING_FOR_ACTIVATION] = "fixating-for-activation",
2769 [HOME_FIXATING_FOR_ACQUIRE] = "fixating-for-acquire",
2770 [HOME_ACTIVATING] = "activating",
2771 [HOME_ACTIVATING_FOR_ACQUIRE] = "activating-for-acquire",
2772 [HOME_DEACTIVATING] = "deactivating",
2773 [HOME_ACTIVE] = "active",
2774 [HOME_LOCKING] = "locking",
2775 [HOME_LOCKED] = "locked",
2776 [HOME_UNLOCKING] = "unlocking",
2777 [HOME_UNLOCKING_FOR_ACQUIRE] = "unlocking-for-acquire",
2778 [HOME_CREATING] = "creating",
2779 [HOME_REMOVING] = "removing",
2780 [HOME_UPDATING] = "updating",
2781 [HOME_UPDATING_WHILE_ACTIVE] = "updating-while-active",
2782 [HOME_RESIZING] = "resizing",
2783 [HOME_RESIZING_WHILE_ACTIVE] = "resizing-while-active",
2784 [HOME_PASSWD] = "passwd",
2785 [HOME_PASSWD_WHILE_ACTIVE] = "passwd-while-active",
2786 [HOME_AUTHENTICATING] = "authenticating",
2787 [HOME_AUTHENTICATING_WHILE_ACTIVE] = "authenticating-while-active",
2788 [HOME_AUTHENTICATING_FOR_ACQUIRE] = "authenticating-for-acquire",
2789};
2790
2791DEFINE_STRING_TABLE_LOOKUP(home_state, HomeState);