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