]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/home/homework.c
varlink,json: introduce new varlink_dispatch() helper
[thirdparty/systemd.git] / src / home / homework.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
70a5db58
LP
2
3#include <stddef.h>
4#include <sys/mount.h>
5
b25a930f 6#include "blockdev-util.h"
70a5db58
LP
7#include "chown-recursive.h"
8#include "copy.h"
9#include "fd-util.h"
10#include "fileio.h"
7c604e89 11#include "filesystems.h"
1dfe5de0 12#include "fs-util.h"
70a5db58
LP
13#include "home-util.h"
14#include "homework-cifs.h"
15#include "homework-directory.h"
7b78db28 16#include "homework-fido2.h"
70a5db58
LP
17#include "homework-fscrypt.h"
18#include "homework-luks.h"
19#include "homework-mount.h"
20#include "homework-pkcs11.h"
21#include "homework.h"
0e98d17e 22#include "libcrypt-util.h"
70a5db58
LP
23#include "main-func.h"
24#include "memory-util.h"
25#include "missing_magic.h"
26#include "mount-util.h"
27#include "path-util.h"
73d874ba 28#include "recovery-key.h"
70a5db58
LP
29#include "rm-rf.h"
30#include "stat-util.h"
31#include "strv.h"
86019efa 32#include "sync-util.h"
70a5db58
LP
33#include "tmpfile-util.h"
34#include "user-util.h"
35#include "virt.h"
36
37/* Make sure a bad password always results in a 3s delay, no matter what */
38#define BAD_PASSWORD_DELAY_USEC (3 * USEC_PER_SEC)
39
40int user_record_authenticate(
41 UserRecord *h,
42 UserRecord *secret,
7b78db28 43 PasswordCache *cache,
c8f145ad 44 bool strict_verify) {
70a5db58 45
17e7561a
LP
46 bool need_password = false, need_recovery_key = false, need_token = false, need_pin = false,
47 need_protected_authentication_path_permitted = false, need_user_presence_permitted = false,
48 need_user_verification_permitted = false, pin_locked = false, pin_incorrect = false,
49 pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false, token_action_timeout = false;
70a5db58
LP
50 int r;
51
52 assert(h);
53 assert(secret);
54
55 /* Tries to authenticate a user record with the supplied secrets. i.e. checks whether at least one
56 * supplied plaintext passwords matches a hashed password field of the user record. Or if a
7b78db28 57 * configured PKCS#11 or FIDO2 token is around and can unlock the record.
70a5db58 58 *
7b78db28
LP
59 * Note that the 'cache' parameter is both an input and output parameter: it contains lists of
60 * configured, decrypted PKCS#11/FIDO2 passwords. We typically have to call this function multiple
61 * times over the course of an operation (think: on login we authenticate the host user record, the
62 * record embedded in the LUKS record and the one embedded in $HOME). Hence we keep a list of
63 * passwords we already decrypted, so that we don't have to do the (slow and potentially interactive)
64 * PKCS#11/FIDO2 dance for the relevant token again and again. */
70a5db58
LP
65
66 /* First, let's see if the supplied plain-text passwords work? */
87d7893c
LP
67 r = user_record_test_password(h, secret);
68 if (r == -ENOKEY)
70a5db58 69 need_password = true;
87d7893c 70 else if (r == -ENXIO)
70a5db58
LP
71 log_debug_errno(r, "User record has no hashed passwords, plaintext passwords not tested.");
72 else if (r < 0)
73 return log_error_errno(r, "Failed to validate password of record: %m");
74 else {
75 log_info("Provided password unlocks user record.");
c8f145ad 76 return 1;
70a5db58
LP
77 }
78
87d7893c
LP
79 /* Similar, but test against the recovery keys */
80 r = user_record_test_recovery_key(h, secret);
81 if (r == -ENOKEY)
82 need_recovery_key = true;
83 else if (r == -ENXIO)
84 log_debug_errno(r, "User record has no recovery keys, plaintext passwords not tested against it.");
85 else if (r < 0)
86 return log_error_errno(r, "Failed to validate the recovery key of the record: %m");
87 else {
88 log_info("Provided password is a recovery key that unlocks the user record.");
89 return 1;
90 }
91
92 if (need_password && need_recovery_key)
93 log_info("None of the supplied plaintext passwords unlock the user record's hashed passwords or recovery keys.");
94 else if (need_password)
95 log_info("None of the supplied plaintext passwords unlock the user record's hashed passwords.");
96 else
97 log_info("None of the supplied plaintext passwords unlock the user record's hashed recovery keys.");
98
7b78db28 99 /* Second, test cached PKCS#11 passwords */
de010b0b 100 for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++)
7b78db28
LP
101 STRV_FOREACH(pp, cache->pkcs11_passwords) {
102 r = test_password_one(h->pkcs11_encrypted_key[n].hashed_password, *pp);
70a5db58
LP
103 if (r < 0)
104 return log_error_errno(r, "Failed to check supplied PKCS#11 password: %m");
105 if (r > 0) {
106 log_info("Previously acquired PKCS#11 password unlocks user record.");
c8f145ad 107 return 1;
70a5db58
LP
108 }
109 }
7b78db28
LP
110
111 /* Third, test cached FIDO2 passwords */
de010b0b 112 for (size_t n = 0; n < h->n_fido2_hmac_salt; n++)
7b78db28
LP
113 /* See if any of the previously calculated passwords work */
114 STRV_FOREACH(pp, cache->fido2_passwords) {
115 r = test_password_one(h->fido2_hmac_salt[n].hashed_password, *pp);
116 if (r < 0)
117 return log_error_errno(r, "Failed to check supplied FIDO2 password: %m");
118 if (r > 0) {
119 log_info("Previously acquired FIDO2 password unlocks user record.");
e4961427 120 return 1;
7b78db28
LP
121 }
122 }
7b78db28
LP
123
124 /* Fourth, let's see if any of the PKCS#11 security tokens are plugged in and help us */
125 for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++) {
126#if HAVE_P11KIT
127 _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
128 .user_record = h,
129 .secret = secret,
130 .encrypted_key = h->pkcs11_encrypted_key + n,
131 };
70a5db58
LP
132
133 r = pkcs11_find_token(data.encrypted_key->uri, pkcs11_callback, &data);
134 switch (r) {
135 case -EAGAIN:
136 need_token = true;
137 break;
138 case -ENOANO:
139 need_pin = true;
140 break;
141 case -ERFKILL:
142 need_protected_authentication_path_permitted = true;
143 break;
144 case -EOWNERDEAD:
145 pin_locked = true;
146 break;
147 case -ENOLCK:
148 pin_incorrect = true;
149 break;
150 case -ETOOMANYREFS:
151 pin_incorrect = pin_incorrect_few_tries_left = true;
152 break;
153 case -EUCLEAN:
154 pin_incorrect = pin_incorrect_few_tries_left = pin_incorrect_one_try_left = true;
155 break;
156 default:
157 if (r < 0)
158 return r;
159
160 r = test_password_one(data.encrypted_key->hashed_password, data.decrypted_password);
161 if (r < 0)
162 return log_error_errno(r, "Failed to test PKCS#11 password: %m");
163 if (r == 0)
164 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Configured PKCS#11 security token %s does not decrypt encrypted key correctly.", data.encrypted_key->uri);
165
166 log_info("Decrypted password from PKCS#11 security token %s unlocks user record.", data.encrypted_key->uri);
167
7b78db28
LP
168 r = strv_extend(&cache->pkcs11_passwords, data.decrypted_password);
169 if (r < 0)
170 return log_oom();
171
e4961427 172 return 1;
7b78db28
LP
173 }
174#else
175 need_token = true;
176 break;
177#endif
178 }
179
180 /* Fifth, let's see if any of the FIDO2 security tokens are plugged in and help us */
181 for (size_t n = 0; n < h->n_fido2_hmac_salt; n++) {
182#if HAVE_LIBFIDO2
183 _cleanup_(erase_and_freep) char *decrypted_password = NULL;
184
185 r = fido2_use_token(h, secret, h->fido2_hmac_salt + n, &decrypted_password);
186 switch (r) {
187 case -EAGAIN:
188 need_token = true;
189 break;
190 case -ENOANO:
191 need_pin = true;
192 break;
193 case -EOWNERDEAD:
194 pin_locked = true;
195 break;
196 case -ENOLCK:
197 pin_incorrect = true;
198 break;
199 case -EMEDIUMTYPE:
200 need_user_presence_permitted = true;
201 break;
17e7561a
LP
202 case -ENOCSI:
203 need_user_verification_permitted = true;
204 break;
7b78db28
LP
205 case -ENOSTR:
206 token_action_timeout = true;
207 break;
208 default:
209 if (r < 0)
210 return r;
211
212 r = test_password_one(h->fido2_hmac_salt[n].hashed_password, decrypted_password);
213 if (r < 0)
214 return log_error_errno(r, "Failed to test FIDO2 password: %m");
215 if (r == 0)
216 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Configured FIDO2 security token does not decrypt encrypted key correctly.");
217
218 log_info("Decrypted password from FIDO2 security token unlocks user record.");
219
220 r = strv_extend(&cache->fido2_passwords, decrypted_password);
70a5db58
LP
221 if (r < 0)
222 return log_oom();
223
c8f145ad 224 return 1;
70a5db58
LP
225 }
226#else
227 need_token = true;
228 break;
229#endif
230 }
231
232 /* Ordered by "relevance", i.e. the most "important" or "interesting" error condition is returned. */
233 if (pin_incorrect_one_try_left)
234 return -EUCLEAN;
235 if (pin_incorrect_few_tries_left)
236 return -ETOOMANYREFS;
237 if (pin_incorrect)
238 return -ENOLCK;
239 if (pin_locked)
240 return -EOWNERDEAD;
7b78db28
LP
241 if (token_action_timeout)
242 return -ENOSTR;
70a5db58
LP
243 if (need_protected_authentication_path_permitted)
244 return -ERFKILL;
7b78db28
LP
245 if (need_user_presence_permitted)
246 return -EMEDIUMTYPE;
17e7561a
LP
247 if (need_user_verification_permitted)
248 return -ENOCSI;
70a5db58
LP
249 if (need_pin)
250 return -ENOANO;
251 if (need_token)
252 return -EBADSLT;
253 if (need_password)
254 return -ENOKEY;
87d7893c
LP
255 if (need_recovery_key)
256 return -EREMOTEIO;
70a5db58 257
87d7893c
LP
258 /* Hmm, this means neither PCKS#11/FIDO2 nor classic hashed passwords or recovery keys were supplied,
259 * we cannot authenticate this reasonably */
c8f145ad
LP
260 if (strict_verify)
261 return log_debug_errno(SYNTHETIC_ERRNO(EKEYREVOKED),
87d7893c 262 "No hashed passwords, no recovery keys and no PKCS#11/FIDO2 tokens defined, cannot authenticate user record, refusing.");
c8f145ad
LP
263
264 /* If strict verification is off this means we are possibly in the case where we encountered an
265 * unfixated record, i.e. a synthetic one that accordingly lacks any authentication data. In this
266 * case, allow the authentication to pass for now, so that the second (or third) authentication level
267 * (the ones of the user record in the LUKS header or inside the home directory) will then catch
268 * invalid passwords. The second/third authentication always runs in strict verification mode. */
87d7893c 269 log_debug("No hashed passwords, not recovery keys and no PKCS#11 tokens defined in record, cannot authenticate user record. "
c8f145ad
LP
270 "Deferring to embedded user record.");
271 return 0;
70a5db58
LP
272}
273
86019efa
LP
274static void drop_caches_now(void) {
275 int r;
276
0e685823 277 /* Drop file system caches now. See https://docs.kernel.org/admin-guide/sysctl/vm.html
2f8211c6
ZJS
278 * for details. We write "2" into /proc/sys/vm/drop_caches to ensure dentries/inodes are flushed, but
279 * not more. */
86019efa
LP
280
281 r = write_string_file("/proc/sys/vm/drop_caches", "2\n", WRITE_STRING_FILE_DISABLE_BUFFER);
282 if (r < 0)
283 log_warning_errno(r, "Failed to drop caches, ignoring: %m");
284 else
285 log_debug("Dropped caches.");
286}
287
55166094
LP
288int home_setup_undo_mount(HomeSetup *setup, int level) {
289 int r;
290
291 assert(setup);
292
293 if (!setup->undo_mount)
294 return 0;
295
1147c538
LP
296 r = umount_recursive(HOME_RUNTIME_WORK_DIR, 0);
297 if (r < 0) {
298 if (level >= LOG_DEBUG) /* umount_recursive() does debug level logging anyway, no need to
299 * repeat that here */
300 return r;
301
a6f44d61 302 /* If a higher log level is requested, the generate a non-debug message here too. */
1147c538
LP
303 return log_full_errno(level, r, "Failed to unmount mount tree below %s: %m", HOME_RUNTIME_WORK_DIR);
304 }
55166094
LP
305
306 setup->undo_mount = false;
307 return 1;
308}
309
f7800049
LP
310int home_setup_undo_dm(HomeSetup *setup, int level) {
311 int r, ret;
312
313 assert(setup);
314
315 if (setup->undo_dm) {
316 assert(setup->crypt_device);
317 assert(setup->dm_name);
318
319 r = sym_crypt_deactivate_by_name(setup->crypt_device, setup->dm_name, 0);
320 if (r < 0)
321 return log_full_errno(level, r, "Failed to deactivate LUKS device: %m");
322
491347bd
LP
323 /* In case the device was already remove asynchronously by an early unmount via the deferred
324 * remove logic, let's wait for it */
325 (void) wait_for_block_device_gone(setup, USEC_PER_SEC * 30);
326
f7800049
LP
327 setup->undo_dm = false;
328 ret = 1;
329 } else
330 ret = 0;
331
332 if (setup->crypt_device) {
333 sym_crypt_free(setup->crypt_device);
334 setup->crypt_device = NULL;
335 }
336
337 return ret;
338}
339
d26cdde3
LP
340int keyring_unlink(key_serial_t k) {
341
342 if (k == -1) /* already invalidated? */
343 return -1;
344
345 if (keyctl(KEYCTL_UNLINK, k, KEY_SPEC_SESSION_KEYRING, 0, 0) < 0)
346 log_debug_errno(errno, "Failed to unlink key from session kernel keyring, ignoring: %m");
347
348 return -1; /* Always return the key_serial_t value for "invalid" */
349}
350
351static int keyring_flush(UserRecord *h) {
352 _cleanup_free_ char *name = NULL;
353 long serial;
354
355 assert(h);
356
357 name = strjoin("homework-user-", h->user_name);
358 if (!name)
359 return log_oom();
360
361 serial = keyctl(KEYCTL_SEARCH, (unsigned long) KEY_SPEC_SESSION_KEYRING, (unsigned long) "user", (unsigned long) name, 0);
362 if (serial == -1)
363 return log_debug_errno(errno, "Failed to find kernel keyring entry for user, ignoring: %m");
364
365 return keyring_unlink(serial);
366}
367
66aa51f8 368int home_setup_done(HomeSetup *setup) {
70a5db58
LP
369 int r = 0, q;
370
371 assert(setup);
372
28a7f106
LP
373 if (setup->root_fd >= 0) {
374 if (setup->do_offline_fitrim) {
375 q = run_fitrim(setup->root_fd);
376 if (q < 0)
377 r = q;
378 }
379
86019efa
LP
380 if (syncfs(setup->root_fd) < 0)
381 log_debug_errno(errno, "Failed to synchronize home directory, ignoring: %m");
382
28a7f106
LP
383 setup->root_fd = safe_close(setup->root_fd);
384 }
70a5db58 385
55166094
LP
386 q = home_setup_undo_mount(setup, LOG_DEBUG);
387 if (q < 0)
388 r = q;
70a5db58 389
f7800049
LP
390 q = home_setup_undo_dm(setup, LOG_DEBUG);
391 if (q < 0)
392 r = q;
70a5db58 393
28a7f106
LP
394 if (setup->image_fd >= 0) {
395 if (setup->do_offline_fallocate) {
396 q = run_fallocate(setup->image_fd, NULL);
397 if (q < 0)
398 r = q;
399 }
400
565ac8b1
LP
401 if (setup->do_mark_clean) {
402 q = run_mark_dirty(setup->image_fd, false);
403 if (q < 0)
404 r = q;
405 }
406
28a7f106
LP
407 setup->image_fd = safe_close(setup->image_fd);
408 }
409
32dda527
LP
410 if (setup->temporary_image_path) {
411 if (unlink(setup->temporary_image_path) < 0)
412 log_debug_errno(errno, "Failed to remove temporary image file '%s', ignoring: %m",
413 setup->temporary_image_path);
414
415 setup->temporary_image_path = mfree(setup->temporary_image_path);
416 }
417
d26cdde3
LP
418 setup->key_serial = keyring_unlink(setup->key_serial);
419
70a5db58
LP
420 setup->undo_mount = false;
421 setup->undo_dm = false;
28a7f106
LP
422 setup->do_offline_fitrim = false;
423 setup->do_offline_fallocate = false;
565ac8b1 424 setup->do_mark_clean = false;
70a5db58
LP
425
426 setup->dm_name = mfree(setup->dm_name);
427 setup->dm_node = mfree(setup->dm_node);
428
429 setup->loop = loop_device_unref(setup->loop);
70a5db58 430
fc4941d6 431 setup->volume_key = erase_and_free(setup->volume_key);
70a5db58
LP
432 setup->volume_key_size = 0;
433
86019efa
LP
434 if (setup->do_drop_caches)
435 drop_caches_now();
436
bf15879b
LP
437 setup->mount_suffix = mfree(setup->mount_suffix);
438
70a5db58
LP
439 return r;
440}
441
aa0a6214 442int home_setup(
70a5db58 443 UserRecord *h,
e1df968b 444 HomeSetupFlags flags,
70a5db58 445 HomeSetup *setup,
c00b2ddc 446 PasswordCache *cache,
70a5db58
LP
447 UserRecord **ret_header_home) {
448
449 int r;
450
451 assert(h);
452 assert(setup);
453 assert(!setup->loop);
454 assert(!setup->crypt_device);
455 assert(setup->root_fd < 0);
456 assert(!setup->undo_dm);
457 assert(!setup->undo_mount);
458
459 /* Makes a home directory accessible (through the root_fd file descriptor, not by path!). */
460
e1df968b 461 if (!FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED)) /* If we set up the directory, we should also drop caches once we are done */
86019efa
LP
462 setup->do_drop_caches = setup->do_drop_caches || user_record_drop_caches(h);
463
70a5db58
LP
464 switch (user_record_storage(h)) {
465
466 case USER_LUKS:
c00b2ddc 467 return home_setup_luks(h, flags, NULL, setup, cache, ret_header_home);
70a5db58
LP
468
469 case USER_SUBVOLUME:
470 case USER_DIRECTORY:
e1df968b 471 r = home_setup_directory(h, setup);
70a5db58
LP
472 break;
473
474 case USER_FSCRYPT:
c00b2ddc 475 r = home_setup_fscrypt(h, setup, cache);
70a5db58
LP
476 break;
477
478 case USER_CIFS:
e1df968b 479 r = home_setup_cifs(h, flags, setup);
70a5db58
LP
480 break;
481
482 default:
483 return log_error_errno(SYNTHETIC_ERRNO(ENOLINK), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
484 }
485
486 if (r < 0)
487 return r;
488
489 if (ret_header_home)
490 *ret_header_home = NULL;
491
492 return r;
493}
494
495int home_sync_and_statfs(int root_fd, struct statfs *ret) {
496 assert(root_fd >= 0);
497
498 /* Let's sync this to disk, so that the disk space reported by fstatfs() below is accurate (for file
499 * systems such as btrfs where this is determined lazily). */
500
501 if (syncfs(root_fd) < 0)
502 return log_error_errno(errno, "Failed to synchronize file system: %m");
503
504 if (ret)
505 if (fstatfs(root_fd, ret) < 0)
506 return log_error_errno(errno, "Failed to statfs() file system: %m");
507
508 log_info("Synchronized disk.");
509
510 return 0;
511}
512
513static int read_identity_file(int root_fd, JsonVariant **ret) {
5d2a48da 514 _cleanup_fclose_ FILE *identity_file = NULL;
254d1313 515 _cleanup_close_ int identity_fd = -EBADF;
70a5db58
LP
516 unsigned line, column;
517 int r;
518
519 assert(root_fd >= 0);
520 assert(ret);
521
522 identity_fd = openat(root_fd, ".identity", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK);
523 if (identity_fd < 0)
524 return log_error_errno(errno, "Failed to open .identity file in home directory: %m");
525
526 r = fd_verify_regular(identity_fd);
527 if (r < 0)
528 return log_error_errno(r, "Embedded identity file is not a regular file, refusing: %m");
529
4fa744a3 530 identity_file = take_fdopen(&identity_fd, "r");
70a5db58
LP
531 if (!identity_file)
532 return log_oom();
533
70a5db58
LP
534 r = json_parse_file(identity_file, ".identity", JSON_PARSE_SENSITIVE, ret, &line, &column);
535 if (r < 0)
536 return log_error_errno(r, "[.identity:%u:%u] Failed to parse JSON data: %m", line, column);
537
538 log_info("Read embedded .identity file.");
539
540 return 0;
541}
542
543static int write_identity_file(int root_fd, JsonVariant *v, uid_t uid) {
544 _cleanup_(json_variant_unrefp) JsonVariant *normalized = NULL;
5d2a48da 545 _cleanup_fclose_ FILE *identity_file = NULL;
254d1313 546 _cleanup_close_ int identity_fd = -EBADF;
70a5db58
LP
547 _cleanup_free_ char *fn = NULL;
548 int r;
549
550 assert(root_fd >= 0);
551 assert(v);
552
553 normalized = json_variant_ref(v);
554
555 r = json_variant_normalize(&normalized);
556 if (r < 0)
557 log_warning_errno(r, "Failed to normalize user record, ignoring: %m");
558
559 r = tempfn_random(".identity", NULL, &fn);
560 if (r < 0)
561 return r;
562
563 identity_fd = openat(root_fd, fn, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
564 if (identity_fd < 0)
565 return log_error_errno(errno, "Failed to create .identity file in home directory: %m");
566
4fa744a3 567 identity_file = take_fdopen(&identity_fd, "w");
70a5db58
LP
568 if (!identity_file) {
569 r = log_oom();
570 goto fail;
571 }
572
70a5db58
LP
573 json_variant_dump(normalized, JSON_FORMAT_PRETTY, identity_file, NULL);
574
575 r = fflush_and_check(identity_file);
576 if (r < 0) {
577 log_error_errno(r, "Failed to write .identity file: %m");
578 goto fail;
579 }
580
581 if (fchown(fileno(identity_file), uid, uid) < 0) {
b05f4495 582 r = log_error_errno(errno, "Failed to change ownership of identity file: %m");
70a5db58
LP
583 goto fail;
584 }
585
586 if (renameat(root_fd, fn, root_fd, ".identity") < 0) {
587 r = log_error_errno(errno, "Failed to move identity file into place: %m");
588 goto fail;
589 }
590
591 log_info("Wrote embedded .identity file.");
592
593 return 0;
594
595fail:
596 (void) unlinkat(root_fd, fn, 0);
597 return r;
598}
599
600int home_load_embedded_identity(
601 UserRecord *h,
602 int root_fd,
603 UserRecord *header_home,
604 UserReconcileMode mode,
7b78db28 605 PasswordCache *cache,
70a5db58
LP
606 UserRecord **ret_embedded_home,
607 UserRecord **ret_new_home) {
608
609 _cleanup_(user_record_unrefp) UserRecord *embedded_home = NULL, *intermediate_home = NULL, *new_home = NULL;
610 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
611 int r;
612
613 assert(h);
614 assert(root_fd >= 0);
615
616 r = read_identity_file(root_fd, &v);
617 if (r < 0)
618 return r;
619
620 embedded_home = user_record_new();
621 if (!embedded_home)
622 return log_oom();
623
bfc0cc1a 624 r = user_record_load(embedded_home, v, USER_RECORD_LOAD_EMBEDDED|USER_RECORD_PERMISSIVE);
70a5db58
LP
625 if (r < 0)
626 return r;
627
628 if (!user_record_compatible(h, embedded_home))
80ace4f2 629 return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "Embedded home record not compatible with host record, refusing.");
70a5db58
LP
630
631 /* Insist that credentials the user supplies also unlocks any embedded records. */
7b78db28 632 r = user_record_authenticate(embedded_home, h, cache, /* strict_verify= */ true);
70a5db58
LP
633 if (r < 0)
634 return r;
c8f145ad 635 assert(r > 0); /* Insist that a password was verified */
70a5db58
LP
636
637 /* At this point we have three records to deal with:
638 *
639 * · The record we got passed from the host
640 * · The record included in the LUKS header (only if LUKS is used)
641 * · The record in the home directory itself (~.identity)
642 *
643 * Now we have to reconcile all three, and let the newest one win. */
644
645 if (header_home) {
646 /* Note we relax the requirements here. Instead of insisting that the host record is strictly
647 * newer, let's also be OK if its equally new. If it is, we'll however insist that the
648 * embedded record must be newer, so that we update at least one of the two. */
649
650 r = user_record_reconcile(h, header_home, mode == USER_RECONCILE_REQUIRE_NEWER ? USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL : mode, &intermediate_home);
651 if (r == -EREMCHG) /* this was supposed to be checked earlier already, but let's check this again */
652 return log_error_errno(r, "Identity stored on host and in header don't match, refusing.");
653 if (r == -ESTALE)
654 return log_error_errno(r, "Embedded identity record is newer than supplied record, refusing.");
655 if (r < 0)
656 return log_error_errno(r, "Failed to reconcile host and header identities: %m");
657 if (r == USER_RECONCILE_EMBEDDED_WON)
658 log_info("Reconciling header user identity completed (header version was newer).");
659 else if (r == USER_RECONCILE_HOST_WON) {
660 log_info("Reconciling header user identity completed (host version was newer).");
661
662 if (mode == USER_RECONCILE_REQUIRE_NEWER) /* Host version is newer than the header
663 * version, hence we'll update
664 * something. This means we can relax the
665 * requirements on the embedded
666 * identity. */
667 mode = USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL;
668 } else {
669 assert(r == USER_RECONCILE_IDENTICAL);
670 log_info("Reconciling user identities completed (host and header version were identical).");
671 }
672
673 h = intermediate_home;
674 }
675
676 r = user_record_reconcile(h, embedded_home, mode, &new_home);
677 if (r == -EREMCHG)
678 return log_error_errno(r, "Identity stored on host and in home don't match, refusing.");
679 if (r == -ESTALE)
680 return log_error_errno(r, "Embedded identity record is equally new or newer than supplied record, refusing.");
681 if (r < 0)
682 return log_error_errno(r, "Failed to reconcile host and embedded identities: %m");
683 if (r == USER_RECONCILE_EMBEDDED_WON)
684 log_info("Reconciling embedded user identity completed (embedded version was newer).");
685 else if (r == USER_RECONCILE_HOST_WON)
686 log_info("Reconciling embedded user identity completed (host version was newer).");
687 else {
688 assert(r == USER_RECONCILE_IDENTICAL);
689 log_info("Reconciling embedded user identity completed (host and embedded version were identical).");
690 }
691
692 if (ret_embedded_home)
693 *ret_embedded_home = TAKE_PTR(embedded_home);
694
695 if (ret_new_home)
696 *ret_new_home = TAKE_PTR(new_home);
697
698 return 0;
699}
700
701int home_store_embedded_identity(UserRecord *h, int root_fd, uid_t uid, UserRecord *old_home) {
702 _cleanup_(user_record_unrefp) UserRecord *embedded = NULL;
703 int r;
704
705 assert(h);
706 assert(root_fd >= 0);
707 assert(uid_is_valid(uid));
708
bfc0cc1a 709 r = user_record_clone(h, USER_RECORD_EXTRACT_EMBEDDED|USER_RECORD_PERMISSIVE, &embedded);
70a5db58
LP
710 if (r < 0)
711 return log_error_errno(r, "Failed to determine new embedded record: %m");
712
713 if (old_home && user_record_equal(old_home, embedded)) {
714 log_debug("Not updating embedded home record.");
715 return 0;
716 }
717
718 /* The identity has changed, let's update it in the image */
719 r = write_identity_file(root_fd, embedded->json, h->uid);
720 if (r < 0)
721 return r;
722
723 return 1;
724}
725
726static const char *file_system_type_fd(int fd) {
727 struct statfs sfs;
728
729 assert(fd >= 0);
730
731 if (fstatfs(fd, &sfs) < 0) {
732 log_debug_errno(errno, "Failed to statfs(): %m");
733 return NULL;
734 }
735
7c604e89 736 return fs_type_to_string(sfs.f_type);
70a5db58
LP
737}
738
739int home_extend_embedded_identity(UserRecord *h, UserRecord *used, HomeSetup *setup) {
740 int r;
741
742 assert(h);
743 assert(used);
744 assert(setup);
745
746 r = user_record_add_binding(
747 h,
748 user_record_storage(used),
749 user_record_image_path(used),
750 setup->found_partition_uuid,
751 setup->found_luks_uuid,
752 setup->found_fs_uuid,
71eceff6
LP
753 setup->crypt_device ? sym_crypt_get_cipher(setup->crypt_device) : NULL,
754 setup->crypt_device ? sym_crypt_get_cipher_mode(setup->crypt_device) : NULL,
70a5db58
LP
755 setup->crypt_device ? luks_volume_key_size_convert(setup->crypt_device) : UINT64_MAX,
756 file_system_type_fd(setup->root_fd),
757 user_record_home_directory(used),
758 used->uid,
759 (gid_t) used->uid);
760 if (r < 0)
761 return log_error_errno(r, "Failed to update binding in record: %m");
762
763 return 0;
764}
765
766static int chown_recursive_directory(int root_fd, uid_t uid) {
767 int r;
768
769 assert(root_fd >= 0);
770 assert(uid_is_valid(uid));
771
772 r = fd_chown_recursive(root_fd, uid, (gid_t) uid, 0777);
773 if (r < 0)
774 return log_error_errno(r, "Failed to change ownership of files and directories: %m");
775 if (r == 0)
776 log_info("Recursive changing of ownership not necessary, skipped.");
777 else
778 log_info("Recursive changing of ownership completed.");
779
780 return 0;
781}
782
cf5115f6
LP
783int home_maybe_shift_uid(
784 UserRecord *h,
6f2c8136 785 HomeSetupFlags flags,
cf5115f6
LP
786 HomeSetup *setup) {
787
254d1313 788 _cleanup_close_ int mount_fd = -EBADF;
cf5115f6
LP
789 struct stat st;
790
791 assert(h);
792 assert(setup);
793 assert(setup->root_fd >= 0);
794
6f2c8136
LP
795 /* If the home dir is already activated, then the UID shift is already applied. */
796 if (FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED))
797 return 0;
798
cf5115f6
LP
799 if (fstat(setup->root_fd, &st) < 0)
800 return log_error_errno(errno, "Failed to stat() home directory: %m");
801
802 /* Let's shift UIDs of this mount. Hopefully this makes the later chowning unnecessary. (Note that we
803 * also prefer to do UID mapping even if the UID already matches our goal UID. That's because we want
804 * to leave UIDs in the homed managed range unmapped.) */
805 (void) home_shift_uid(setup->root_fd, NULL, st.st_uid, h->uid, &mount_fd);
806
807 /* If this worked, then we'll have a reference to the mount now, which we can also use like an O_PATH
808 * fd to the new dir. Let's convert it into a proper O_DIRECTORY fd. */
809 if (mount_fd >= 0) {
810 safe_close(setup->root_fd);
811
812 setup->root_fd = fd_reopen(mount_fd, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
813 if (setup->root_fd < 0)
814 return log_error_errno(setup->root_fd, "Failed to convert mount fd into regular directory fd: %m");
815 }
816
817 return 0;
818}
819
70a5db58
LP
820int home_refresh(
821 UserRecord *h,
6f2c8136 822 HomeSetupFlags flags,
70a5db58
LP
823 HomeSetup *setup,
824 UserRecord *header_home,
7b78db28 825 PasswordCache *cache,
70a5db58
LP
826 struct statfs *ret_statfs,
827 UserRecord **ret_new_home) {
828
829 _cleanup_(user_record_unrefp) UserRecord *embedded_home = NULL, *new_home = NULL;
830 int r;
831
832 assert(h);
833 assert(setup);
834 assert(ret_new_home);
835
836 /* When activating a home directory, does the identity work: loads the identity from the $HOME
837 * directory, reconciles it with our idea, chown()s everything. */
838
7b78db28 839 r = home_load_embedded_identity(h, setup->root_fd, header_home, USER_RECONCILE_ANY, cache, &embedded_home, &new_home);
70a5db58
LP
840 if (r < 0)
841 return r;
842
6f2c8136 843 r = home_maybe_shift_uid(h, flags, setup);
cf5115f6
LP
844 if (r < 0)
845 return r;
846
70a5db58
LP
847 r = home_store_header_identity_luks(new_home, setup, header_home);
848 if (r < 0)
849 return r;
850
851 r = home_store_embedded_identity(new_home, setup->root_fd, h->uid, embedded_home);
852 if (r < 0)
853 return r;
854
855 r = chown_recursive_directory(setup->root_fd, h->uid);
856 if (r < 0)
857 return r;
858
859 r = home_sync_and_statfs(setup->root_fd, ret_statfs);
860 if (r < 0)
861 return r;
862
863 *ret_new_home = TAKE_PTR(new_home);
864 return 0;
865}
866
867static int home_activate(UserRecord *h, UserRecord **ret_home) {
a74e2e44 868 _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
70a5db58 869 _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
a74e2e44 870 _cleanup_(password_cache_free) PasswordCache cache = {};
6f2c8136 871 HomeSetupFlags flags = 0;
70a5db58
LP
872 int r;
873
874 assert(h);
875
876 if (!h->user_name)
877 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
878 if (!uid_is_valid(h->uid))
879 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
880 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
881 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Activating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
882
7b78db28 883 r = user_record_authenticate(h, h, &cache, /* strict_verify= */ false);
70a5db58
LP
884 if (r < 0)
885 return r;
886
887 r = user_record_test_home_directory_and_warn(h);
888 if (r < 0)
889 return r;
890 if (r == USER_TEST_MOUNTED)
891 return log_error_errno(SYNTHETIC_ERRNO(EALREADY), "Home directory %s is already mounted, refusing.", user_record_home_directory(h));
892
893 r = user_record_test_image_path_and_warn(h);
894 if (r < 0)
895 return r;
896 if (r == USER_TEST_ABSENT)
897 return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "Image path %s is missing, refusing.", user_record_image_path(h));
898
899 switch (user_record_storage(h)) {
900
901 case USER_LUKS:
6f2c8136 902 r = home_activate_luks(h, flags, &setup, &cache, &new_home);
70a5db58
LP
903 if (r < 0)
904 return r;
905
906 break;
907
908 case USER_SUBVOLUME:
909 case USER_DIRECTORY:
910 case USER_FSCRYPT:
6f2c8136 911 r = home_activate_directory(h, flags, &setup, &cache, &new_home);
70a5db58
LP
912 if (r < 0)
913 return r;
914
915 break;
916
917 case USER_CIFS:
6f2c8136 918 r = home_activate_cifs(h, flags, &setup, &cache, &new_home);
70a5db58
LP
919 if (r < 0)
920 return r;
921
922 break;
923
924 default:
04499a70 925 assert_not_reached();
70a5db58
LP
926 }
927
928 /* Note that the returned object might either be a reference to an updated version of the existing
929 * home object, or a reference to a newly allocated home object. The caller has to be able to deal
930 * with both, and consider the old object out-of-date. */
931 if (user_record_equal(h, new_home)) {
932 *ret_home = NULL;
933 return 0; /* no identity change */
934 }
935
936 *ret_home = TAKE_PTR(new_home);
937 return 1; /* identity updated */
938}
939
940static int home_deactivate(UserRecord *h, bool force) {
fc032ae1 941 _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
26191000 942 _cleanup_(password_cache_free) PasswordCache cache = {};
70a5db58
LP
943 bool done = false;
944 int r;
945
946 assert(h);
947
948 if (!h->user_name)
949 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record incomplete, refusing.");
950 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
951 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Deactivating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
952
953 r = user_record_test_home_directory_and_warn(h);
954 if (r < 0)
955 return r;
956 if (r == USER_TEST_MOUNTED) {
a71a0693
LP
957 /* Before we do anything, let's move the home mount away. */
958 r = home_unshare_and_mkdir();
959 if (r < 0)
960 return r;
28a7f106 961
a71a0693
LP
962 r = mount_nofollow_verbose(LOG_ERR, user_record_home_directory(h), HOME_RUNTIME_WORK_DIR, NULL, MS_BIND, NULL);
963 if (r < 0)
964 return r;
965
966 setup.undo_mount = true; /* remember to unmount the new bind mount from HOME_RUNTIME_WORK_DIR */
967
968 /* Let's explicitly open the new root fs, using the moved path */
969 setup.root_fd = open(HOME_RUNTIME_WORK_DIR, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
970 if (setup.root_fd < 0)
971 return log_error_errno(errno, "Failed to open moved home directory: %m");
972
973 /* Now get rid of the home at its original place (we only keep the bind mount we created above) */
974 r = umount_verbose(LOG_ERR, user_record_home_directory(h), UMOUNT_NOFOLLOW | (force ? MNT_FORCE|MNT_DETACH : 0));
86019efa 975 if (r < 0)
a71a0693
LP
976 return r;
977
d26cdde3
LP
978 if (user_record_storage(h) == USER_LUKS) {
979 /* Automatically shrink on logout if that's enabled. To be able to shrink we need the
980 * keys to the device. */
981 password_cache_load_keyring(h, &cache);
a71a0693 982 (void) home_trim_luks(h, &setup);
d26cdde3 983 }
a71a0693
LP
984
985 /* Sync explicitly, so that the drop caches logic below can work as documented */
986 if (syncfs(setup.root_fd) < 0)
987 log_debug_errno(errno, "Failed to synchronize home directory, ignoring: %m");
86019efa
LP
988 else
989 log_info("Syncing completed.");
990
26191000
LP
991 if (user_record_storage(h) == USER_LUKS)
992 (void) home_auto_shrink_luks(h, &setup, &cache);
993
a71a0693
LP
994 setup.root_fd = safe_close(setup.root_fd);
995
996 /* Now get rid of the bind mount, too */
997 r = umount_verbose(LOG_ERR, HOME_RUNTIME_WORK_DIR, UMOUNT_NOFOLLOW | (force ? MNT_FORCE|MNT_DETACH : 0));
998 if (r < 0)
999 return r;
1000
1001 setup.undo_mount = false; /* Remember that the bind mount doesn't need to be unmounted anymore */
1002
1003 if (user_record_drop_caches(h))
1004 setup.do_drop_caches = true;
70a5db58
LP
1005
1006 log_info("Unmounting completed.");
1007 done = true;
1008 } else
1009 log_info("Directory %s is already unmounted.", user_record_home_directory(h));
1010
1011 if (user_record_storage(h) == USER_LUKS) {
fc032ae1 1012 r = home_deactivate_luks(h, &setup);
70a5db58
LP
1013 if (r < 0)
1014 return r;
1015 if (r > 0)
1016 done = true;
1017 }
1018
d26cdde3
LP
1019 /* Explicitly flush any per-user key from the keyring */
1020 (void) keyring_flush(h);
1021
70a5db58
LP
1022 if (!done)
1023 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC), "Home is not active.");
1024
a71a0693
LP
1025 if (setup.do_drop_caches) {
1026 setup.do_drop_caches = false;
86019efa 1027 drop_caches_now();
a71a0693 1028 }
86019efa 1029
70a5db58
LP
1030 log_info("Everything completed.");
1031 return 0;
1032}
1033
1034static int copy_skel(int root_fd, const char *skel) {
1035 int r;
1036
1037 assert(root_fd >= 0);
1038
ad6fae7f 1039 r = copy_tree_at(AT_FDCWD, skel, root_fd, ".", UID_INVALID, GID_INVALID, COPY_MERGE|COPY_REPLACE, NULL, NULL);
70a5db58
LP
1040 if (r == -ENOENT) {
1041 log_info("Skeleton directory %s missing, ignoring.", skel);
1042 return 0;
1043 }
1044 if (r < 0)
1045 return log_error_errno(r, "Failed to copy in %s: %m", skel);
1046
1047 log_info("Copying in %s completed.", skel);
1048 return 0;
1049}
1050
1051static int change_access_mode(int root_fd, mode_t m) {
1052 assert(root_fd >= 0);
1053
1054 if (fchmod(root_fd, m) < 0)
1055 return log_error_errno(errno, "Failed to change access mode of top-level directory: %m");
1056
1057 log_info("Changed top-level directory access mode to 0%o.", m);
1058 return 0;
1059}
1060
1061int home_populate(UserRecord *h, int dir_fd) {
1062 int r;
1063
1064 assert(h);
1065 assert(dir_fd >= 0);
1066
1067 r = copy_skel(dir_fd, user_record_skeleton_directory(h));
1068 if (r < 0)
1069 return r;
1070
1071 r = home_store_embedded_identity(h, dir_fd, h->uid, NULL);
1072 if (r < 0)
1073 return r;
1074
1075 r = chown_recursive_directory(dir_fd, h->uid);
1076 if (r < 0)
1077 return r;
1078
1079 r = change_access_mode(dir_fd, user_record_access_mode(h));
1080 if (r < 0)
1081 return r;
1082
1083 return 0;
1084}
1085
1086static int user_record_compile_effective_passwords(
1087 UserRecord *h,
7b78db28
LP
1088 PasswordCache *cache,
1089 char ***ret_effective_passwords) {
70a5db58 1090
5d2a48da 1091 _cleanup_strv_free_erase_ char **effective = NULL;
70a5db58 1092 size_t n;
70a5db58
LP
1093 int r;
1094
1095 assert(h);
7b78db28 1096 assert(cache);
70a5db58
LP
1097
1098 /* We insist on at least one classic hashed password to be defined in addition to any PKCS#11 one, as
1099 * a safe fallback, but also to simplify the password changing algorithm: there we require providing
1100 * the old literal password only (and do not care for the old PKCS#11 token) */
1101
1102 if (strv_isempty(h->hashed_password))
d7a0f1f4
FS
1103 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
1104 "User record has no hashed passwords, refusing.");
70a5db58
LP
1105
1106 /* Generates the list of plaintext passwords to propagate to LUKS/fscrypt devices, and checks whether
1107 * we have a plaintext password for each hashed one. If we are missing one we'll fail, since we
1108 * couldn't sync fscrypt/LUKS to the login account properly. */
1109
1110 STRV_FOREACH(i, h->hashed_password) {
1111 bool found = false;
70a5db58
LP
1112
1113 log_debug("Looking for plaintext password for: %s", *i);
1114
1115 /* Let's scan all provided plaintext passwords */
1116 STRV_FOREACH(j, h->password) {
1117 r = test_password_one(*i, *j);
1118 if (r < 0)
87d7893c 1119 return log_error_errno(r, "Failed to test plaintext password: %m");
70a5db58
LP
1120 if (r > 0) {
1121 if (ret_effective_passwords) {
1122 r = strv_extend(&effective, *j);
1123 if (r < 0)
1124 return log_oom();
1125 }
1126
1127 log_debug("Found literal plaintext password.");
1128 found = true;
1129 break;
1130 }
1131 }
1132
1133 if (!found)
1134 return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), "Missing plaintext password for defined hashed password");
1135 }
1136
87d7893c
LP
1137 for (n = 0; n < h->n_recovery_key; n++) {
1138 bool found = false;
87d7893c
LP
1139
1140 log_debug("Looking for plaintext recovery key for: %s", h->recovery_key[n].hashed_password);
1141
1142 STRV_FOREACH(j, h->password) {
1143 _cleanup_(erase_and_freep) char *mangled = NULL;
1144 const char *p;
1145
1146 if (streq(h->recovery_key[n].type, "modhex64")) {
1147
1148 r = normalize_recovery_key(*j, &mangled);
1149 if (r == -EINVAL) /* Not properly formatted, probably a regular password. */
1150 continue;
1151 if (r < 0)
1152 return log_error_errno(r, "Failed to normalize recovery key: %m");
1153
1154 p = mangled;
1155 } else
1156 p = *j;
1157
1158 r = test_password_one(h->recovery_key[n].hashed_password, p);
1159 if (r < 0)
1160 return log_error_errno(r, "Failed to test plaintext recovery key: %m");
1161 if (r > 0) {
1162 if (ret_effective_passwords) {
1163 r = strv_extend(&effective, p);
1164 if (r < 0)
1165 return log_oom();
1166 }
1167
1168 log_debug("Found plaintext recovery key.");
1169 found = true;
1170 break;
1171 }
1172 }
1173
1174 if (!found)
1175 return log_error_errno(SYNTHETIC_ERRNO(EREMOTEIO), "Missing plaintext recovery key for defined recovery key");
1176 }
1177
70a5db58
LP
1178 for (n = 0; n < h->n_pkcs11_encrypted_key; n++) {
1179#if HAVE_P11KIT
1180 _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
1181 .user_record = h,
1182 .secret = h,
1183 .encrypted_key = h->pkcs11_encrypted_key + n,
1184 };
1185
1186 r = pkcs11_find_token(data.encrypted_key->uri, pkcs11_callback, &data);
1187 if (r == -EAGAIN)
1188 return -EBADSLT;
1189 if (r < 0)
1190 return r;
1191
1192 r = test_password_one(data.encrypted_key->hashed_password, data.decrypted_password);
1193 if (r < 0)
1194 return log_error_errno(r, "Failed to test PKCS#11 password: %m");
1195 if (r == 0)
1196 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Decrypted password from token is not correct, refusing.");
1197
1198 if (ret_effective_passwords) {
1199 r = strv_extend(&effective, data.decrypted_password);
1200 if (r < 0)
1201 return log_oom();
1202 }
1203
7b78db28
LP
1204 r = strv_extend(&cache->pkcs11_passwords, data.decrypted_password);
1205 if (r < 0)
1206 return log_oom();
1207#else
1208 return -EBADSLT;
1209#endif
1210 }
1211
1212 for (n = 0; n < h->n_fido2_hmac_salt; n++) {
1213#if HAVE_LIBFIDO2
1214 _cleanup_(erase_and_freep) char *decrypted_password = NULL;
1215
1216 r = fido2_use_token(h, h, h->fido2_hmac_salt + n, &decrypted_password);
1217 if (r < 0)
1218 return r;
1219
1220 r = test_password_one(h->fido2_hmac_salt[n].hashed_password, decrypted_password);
1221 if (r < 0)
1222 return log_error_errno(r, "Failed to test FIDO2 password: %m");
1223 if (r == 0)
1224 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Decrypted password from token is not correct, refusing.");
1225
1226 if (ret_effective_passwords) {
1227 r = strv_extend(&effective, decrypted_password);
70a5db58
LP
1228 if (r < 0)
1229 return log_oom();
1230 }
7b78db28
LP
1231
1232 r = strv_extend(&cache->fido2_passwords, decrypted_password);
1233 if (r < 0)
1234 return log_oom();
70a5db58
LP
1235#else
1236 return -EBADSLT;
1237#endif
1238 }
1239
1240 if (ret_effective_passwords)
1241 *ret_effective_passwords = TAKE_PTR(effective);
70a5db58
LP
1242
1243 return 0;
1244}
1245
1dfe5de0
LP
1246static int determine_default_storage(UserStorage *ret) {
1247 UserStorage storage = _USER_STORAGE_INVALID;
1248 const char *e;
1249 int r;
1250
1251 assert(ret);
1252
1253 /* homed tells us via an environment variable which default storage to use */
1254 e = getenv("SYSTEMD_HOME_DEFAULT_STORAGE");
1255 if (e) {
1256 storage = user_storage_from_string(e);
1257 if (storage < 0)
1258 log_warning("$SYSTEMD_HOME_DEFAULT_STORAGE set to invalid storage type, ignoring: %s", e);
1259 else {
1260 log_info("Using configured default storage '%s'.", user_storage_to_string(storage));
1261 *ret = storage;
1262 return 0;
1263 }
1264 }
1265
1266 /* When neither user nor admin specified the storage type to use, fix it to be LUKS — unless we run
1267 * in a container where loopback devices and LUKS/DM are not available. Also, if /home is encrypted
1268 * anyway, let's avoid duplicate encryption. Note that we typically default to the assumption of
1269 * "classic" storage for most operations. However, if we create a new home, then let's user LUKS if
1270 * nothing is specified. */
1271
1272 r = detect_container();
1273 if (r < 0)
1274 return log_error_errno(r, "Failed to determine whether we are in a container: %m");
1275 if (r == 0) {
2700fecd 1276 r = path_is_encrypted(get_home_root());
0608e2d3 1277 if (r > 0)
2700fecd 1278 log_info("%s is encrypted, not using '%s' storage, in order to avoid double encryption.", get_home_root(), user_storage_to_string(USER_LUKS));
0608e2d3
LP
1279 else {
1280 if (r < 0)
2700fecd 1281 log_warning_errno(r, "Failed to determine if %s is encrypted, ignoring: %m", get_home_root());
1dfe5de0 1282
0608e2d3
LP
1283 r = dlopen_cryptsetup();
1284 if (r < 0)
1285 log_info("Not using '%s' storage, since libcryptsetup could not be loaded.", user_storage_to_string(USER_LUKS));
1286 else {
1287 log_info("Using automatic default storage of '%s'.", user_storage_to_string(USER_LUKS));
1288 *ret = USER_LUKS;
1289 return 0;
1290 }
1291 }
1dfe5de0
LP
1292 } else
1293 log_info("Running in container, not using '%s' storage.", user_storage_to_string(USER_LUKS));
1294
2700fecd 1295 r = path_is_fs_type(get_home_root(), BTRFS_SUPER_MAGIC);
1dfe5de0 1296 if (r < 0)
2700fecd 1297 log_warning_errno(r, "Failed to determine file system of %s, ignoring: %m", get_home_root());
1dfe5de0 1298 if (r > 0) {
2700fecd 1299 log_info("%s is on btrfs, using '%s' as storage.", get_home_root(), user_storage_to_string(USER_SUBVOLUME));
1dfe5de0
LP
1300 *ret = USER_SUBVOLUME;
1301 } else {
2700fecd 1302 log_info("%s is on simple file system, using '%s' as storage.", get_home_root(), user_storage_to_string(USER_DIRECTORY));
1dfe5de0
LP
1303 *ret = USER_DIRECTORY;
1304 }
1305
1306 return 0;
1307}
1308
70a5db58 1309static int home_create(UserRecord *h, UserRecord **ret_home) {
5d2a48da 1310 _cleanup_strv_free_erase_ char **effective_passwords = NULL;
a74e2e44 1311 _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
70a5db58 1312 _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
7b78db28 1313 _cleanup_(password_cache_free) PasswordCache cache = {};
1dfe5de0
LP
1314 UserStorage new_storage = _USER_STORAGE_INVALID;
1315 const char *new_fs = NULL;
70a5db58
LP
1316 int r;
1317
1318 assert(h);
1319
1320 if (!h->user_name)
1321 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks name, refusing.");
1322 if (!uid_is_valid(h->uid))
1323 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
1324
7b78db28 1325 r = user_record_compile_effective_passwords(h, &cache, &effective_passwords);
70a5db58
LP
1326 if (r < 0)
1327 return r;
1328
1329 r = user_record_test_home_directory_and_warn(h);
1330 if (r < 0)
1331 return r;
1332 if (r != USER_TEST_ABSENT)
1333 return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Home directory %s already exists, refusing.", user_record_home_directory(h));
1334
70a5db58 1335 if (h->storage < 0) {
1dfe5de0 1336 r = determine_default_storage(&new_storage);
70a5db58 1337 if (r < 0)
1dfe5de0
LP
1338 return r;
1339 }
70a5db58 1340
1dfe5de0
LP
1341 if ((h->storage == USER_LUKS ||
1342 (h->storage < 0 && new_storage == USER_LUKS)) &&
1343 !h->file_system_type)
1344 new_fs = getenv("SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE");
70a5db58 1345
1dfe5de0 1346 if (new_storage >= 0 || new_fs) {
70a5db58
LP
1347 r = user_record_add_binding(
1348 h,
1349 new_storage,
1350 NULL,
1351 SD_ID128_NULL,
1352 SD_ID128_NULL,
1353 SD_ID128_NULL,
1354 NULL,
1355 NULL,
1356 UINT64_MAX,
1dfe5de0 1357 new_fs,
70a5db58
LP
1358 NULL,
1359 UID_INVALID,
1360 GID_INVALID);
1361 if (r < 0)
1362 return log_error_errno(r, "Failed to change storage type to LUKS: %m");
70a5db58
LP
1363 }
1364
1365 r = user_record_test_image_path_and_warn(h);
1366 if (r < 0)
1367 return r;
1368 if (!IN_SET(r, USER_TEST_ABSENT, USER_TEST_UNDEFINED, USER_TEST_MAYBE))
1369 return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Image path %s already exists, refusing.", user_record_image_path(h));
1370
1371 switch (user_record_storage(h)) {
1372
1373 case USER_LUKS:
bc5890c6 1374 r = home_create_luks(h, &setup, &cache, effective_passwords, &new_home);
70a5db58
LP
1375 break;
1376
1377 case USER_DIRECTORY:
1378 case USER_SUBVOLUME:
e1aeaf27 1379 r = home_create_directory_or_subvolume(h, &setup, &new_home);
70a5db58
LP
1380 break;
1381
1382 case USER_FSCRYPT:
655807f5 1383 r = home_create_fscrypt(h, &setup, effective_passwords, &new_home);
70a5db58
LP
1384 break;
1385
1386 case USER_CIFS:
a74e2e44 1387 r = home_create_cifs(h, &setup, &new_home);
70a5db58
LP
1388 break;
1389
1390 default:
1391 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY),
1392 "Creating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1393 }
1394 if (r < 0)
1395 return r;
1396
1397 if (user_record_equal(h, new_home)) {
1398 *ret_home = NULL;
1399 return 0;
1400 }
1401
1402 *ret_home = TAKE_PTR(new_home);
1403 return 1;
1404}
1405
1406static int home_remove(UserRecord *h) {
1407 bool deleted = false;
1408 const char *ip, *hd;
1409 int r;
1410
1411 assert(h);
1412
1413 if (!h->user_name)
1414 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
1415 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
1416 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Removing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1417
1418 hd = user_record_home_directory(h);
1419
1420 r = user_record_test_home_directory_and_warn(h);
1421 if (r < 0)
1422 return r;
1423 if (r == USER_TEST_MOUNTED)
1424 return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Directory %s is still mounted, refusing.", hd);
1425
1426 assert(hd);
1427
1428 r = user_record_test_image_path_and_warn(h);
1429 if (r < 0)
1430 return r;
1431
1432 ip = user_record_image_path(h);
1433
1434 switch (user_record_storage(h)) {
1435
1436 case USER_LUKS: {
1437 struct stat st;
1438
1439 assert(ip);
1440
1441 if (stat(ip, &st) < 0) {
6b8664cb 1442 if (errno != ENOENT)
80ace4f2 1443 return log_error_errno(errno, "Failed to stat() %s: %m", ip);
70a5db58
LP
1444
1445 } else {
1446 if (S_ISREG(st.st_mode)) {
1447 if (unlink(ip) < 0) {
1448 if (errno != ENOENT)
1449 return log_error_errno(errno, "Failed to remove %s: %m", ip);
86019efa
LP
1450 } else {
1451 _cleanup_free_ char *parent = NULL;
1452
70a5db58
LP
1453 deleted = true;
1454
86019efa
LP
1455 r = path_extract_directory(ip, &parent);
1456 if (r < 0)
1457 log_debug_errno(r, "Failed to determine parent directory of '%s': %m", ip);
1458 else {
1459 r = fsync_path_at(AT_FDCWD, parent);
1460 if (r < 0)
1461 log_debug_errno(r, "Failed to synchronize disk after deleting '%s', ignoring: %m", ip);
1462 }
1463 }
1464
70a5db58
LP
1465 } else if (S_ISBLK(st.st_mode))
1466 log_info("Not removing file system on block device %s.", ip);
1467 else
1468 return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "Image file %s is neither block device, nor regular, refusing removal.", ip);
1469 }
1470
1471 break;
1472 }
1473
1474 case USER_SUBVOLUME:
1475 case USER_DIRECTORY:
1476 case USER_FSCRYPT:
1477 assert(ip);
1478
86019efa 1479 r = rm_rf(ip, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME|REMOVE_SYNCFS);
70a5db58
LP
1480 if (r < 0) {
1481 if (r != -ENOENT)
1482 return log_warning_errno(r, "Failed to remove %s: %m", ip);
1483 } else
1484 deleted = true;
1485
1486 /* If the image path and the home directory are the same invalidate the home directory, so
1487 * that we don't remove it anymore */
1488 if (path_equal(ip, hd))
1489 hd = NULL;
1490
1491 break;
1492
1493 case USER_CIFS:
1494 /* Nothing else to do here: we won't remove remote stuff. */
1495 log_info("Not removing home directory on remote server.");
1496 break;
1497
1498 default:
04499a70 1499 assert_not_reached();
70a5db58
LP
1500 }
1501
1502 if (hd) {
1503 if (rmdir(hd) < 0) {
1504 if (errno != ENOENT)
1505 return log_error_errno(errno, "Failed to remove %s, ignoring: %m", hd);
1506 } else
1507 deleted = true;
1508 }
1509
86019efa
LP
1510 if (deleted) {
1511 if (user_record_drop_caches(h))
1512 drop_caches_now();
1513
70a5db58 1514 log_info("Everything completed.");
86019efa 1515 } else
e4ff0393
FS
1516 return log_notice_errno(SYNTHETIC_ERRNO(EALREADY),
1517 "Nothing to remove.");
70a5db58
LP
1518
1519 return 0;
1520}
1521
e1df968b 1522static int home_validate_update(UserRecord *h, HomeSetup *setup, HomeSetupFlags *flags) {
70a5db58
LP
1523 bool has_mount = false;
1524 int r;
1525
1526 assert(h);
1527 assert(setup);
1528
1529 if (!h->user_name)
1530 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
1531 if (!uid_is_valid(h->uid))
1532 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
1533 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
1534 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1535
1536 r = user_record_test_home_directory_and_warn(h);
1537 if (r < 0)
1538 return r;
1539
1540 has_mount = r == USER_TEST_MOUNTED;
1541
1542 r = user_record_test_image_path_and_warn(h);
1543 if (r < 0)
1544 return r;
1545 if (r == USER_TEST_ABSENT)
1546 return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "Image path %s does not exist", user_record_image_path(h));
1547
1548 switch (user_record_storage(h)) {
1549
1550 case USER_DIRECTORY:
1551 case USER_SUBVOLUME:
1552 case USER_FSCRYPT:
1553 case USER_CIFS:
1554 break;
1555
1556 case USER_LUKS: {
e1ab6635 1557 r = home_get_state_luks(h, setup);
70a5db58
LP
1558 if (r < 0)
1559 return r;
1560 if ((r > 0) != has_mount)
1561 return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Home mount incompletely set up.");
1562
1563 break;
1564 }
1565
1566 default:
04499a70 1567 assert_not_reached();
70a5db58
LP
1568 }
1569
e1df968b
LP
1570 if (flags)
1571 SET_FLAG(*flags, HOME_SETUP_ALREADY_ACTIVATED, has_mount);
1572
70a5db58
LP
1573 return has_mount; /* return true if the home record is already active */
1574}
1575
1576static int home_update(UserRecord *h, UserRecord **ret) {
1577 _cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *header_home = NULL, *embedded_home = NULL;
66aa51f8 1578 _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
7b78db28 1579 _cleanup_(password_cache_free) PasswordCache cache = {};
e1df968b 1580 HomeSetupFlags flags = 0;
70a5db58
LP
1581 int r;
1582
1583 assert(h);
1584 assert(ret);
1585
7b78db28 1586 r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
70a5db58
LP
1587 if (r < 0)
1588 return r;
c8f145ad 1589 assert(r > 0); /* Insist that a password was verified */
70a5db58 1590
e1df968b 1591 r = home_validate_update(h, &setup, &flags);
70a5db58
LP
1592 if (r < 0)
1593 return r;
1594
c00b2ddc 1595 r = home_setup(h, flags, &setup, &cache, &header_home);
70a5db58
LP
1596 if (r < 0)
1597 return r;
1598
7b78db28 1599 r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER, &cache, &embedded_home, &new_home);
70a5db58
LP
1600 if (r < 0)
1601 return r;
1602
a8be0984
LP
1603 r = home_maybe_shift_uid(h, flags, &setup);
1604 if (r < 0)
1605 return r;
1606
70a5db58
LP
1607 r = home_store_header_identity_luks(new_home, &setup, header_home);
1608 if (r < 0)
1609 return r;
1610
1611 r = home_store_embedded_identity(new_home, setup.root_fd, h->uid, embedded_home);
1612 if (r < 0)
1613 return r;
1614
1615 r = home_extend_embedded_identity(new_home, h, &setup);
1616 if (r < 0)
1617 return r;
1618
1619 r = home_sync_and_statfs(setup.root_fd, NULL);
1620 if (r < 0)
1621 return r;
1622
66aa51f8 1623 r = home_setup_done(&setup);
70a5db58
LP
1624 if (r < 0)
1625 return r;
1626
1627 log_info("Everything completed.");
1628
1629 *ret = TAKE_PTR(new_home);
1630 return 0;
1631}
1632
d357b80d 1633static int home_resize(UserRecord *h, bool automatic, UserRecord **ret) {
66aa51f8 1634 _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
7b78db28 1635 _cleanup_(password_cache_free) PasswordCache cache = {};
e1df968b 1636 HomeSetupFlags flags = 0;
70a5db58
LP
1637 int r;
1638
1639 assert(h);
1640 assert(ret);
1641
1642 if (h->disk_size == UINT64_MAX)
1643 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No target size specified, refusing.");
1644
d357b80d
LP
1645 if (automatic)
1646 /* In automatic mode don't want to ask the user for the password, hence load it from the kernel keyring */
1647 password_cache_load_keyring(h, &cache);
1648 else {
1649 /* In manual mode let's ensure the user is fully authenticated */
1650 r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
1651 if (r < 0)
1652 return r;
1653 assert(r > 0); /* Insist that a password was verified */
1654 }
70a5db58 1655
e1df968b 1656 r = home_validate_update(h, &setup, &flags);
70a5db58
LP
1657 if (r < 0)
1658 return r;
1659
d357b80d
LP
1660 /* In automatic mode let's skip syncing identities, because we can't validate them, since we can't
1661 * ask the user for reauthentication */
1662 if (automatic)
1663 flags |= HOME_SETUP_RESIZE_DONT_SYNC_IDENTITIES;
1664
70a5db58
LP
1665 switch (user_record_storage(h)) {
1666
1667 case USER_LUKS:
c00b2ddc 1668 return home_resize_luks(h, flags, &setup, &cache, ret);
70a5db58
LP
1669
1670 case USER_DIRECTORY:
1671 case USER_SUBVOLUME:
1672 case USER_FSCRYPT:
c00b2ddc 1673 return home_resize_directory(h, flags, &setup, &cache, ret);
70a5db58
LP
1674
1675 default:
1676 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Resizing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1677 }
1678}
1679
1680static int home_passwd(UserRecord *h, UserRecord **ret_home) {
1681 _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *embedded_home = NULL, *new_home = NULL;
5d2a48da 1682 _cleanup_strv_free_erase_ char **effective_passwords = NULL;
66aa51f8 1683 _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
7b78db28 1684 _cleanup_(password_cache_free) PasswordCache cache = {};
e1df968b 1685 HomeSetupFlags flags = 0;
70a5db58
LP
1686 int r;
1687
1688 assert(h);
1689 assert(ret_home);
1690
1691 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT))
1692 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Changing password of home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1693
7b78db28 1694 r = user_record_compile_effective_passwords(h, &cache, &effective_passwords);
70a5db58
LP
1695 if (r < 0)
1696 return r;
1697
e1df968b 1698 r = home_validate_update(h, &setup, &flags);
70a5db58
LP
1699 if (r < 0)
1700 return r;
1701
c00b2ddc 1702 r = home_setup(h, flags, &setup, &cache, &header_home);
70a5db58
LP
1703 if (r < 0)
1704 return r;
1705
7b78db28 1706 r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL, &cache, &embedded_home, &new_home);
70a5db58
LP
1707 if (r < 0)
1708 return r;
1709
a8be0984
LP
1710 r = home_maybe_shift_uid(h, flags, &setup);
1711 if (r < 0)
1712 return r;
1713
70a5db58
LP
1714 switch (user_record_storage(h)) {
1715
1716 case USER_LUKS:
d26cdde3 1717 r = home_passwd_luks(h, flags, &setup, &cache, effective_passwords);
70a5db58
LP
1718 if (r < 0)
1719 return r;
1720 break;
1721
1722 case USER_FSCRYPT:
7b78db28 1723 r = home_passwd_fscrypt(h, &setup, &cache, effective_passwords);
70a5db58
LP
1724 if (r < 0)
1725 return r;
1726 break;
1727
1728 default:
1729 break;
1730 }
1731
1732 r = home_store_header_identity_luks(new_home, &setup, header_home);
1733 if (r < 0)
1734 return r;
1735
1736 r = home_store_embedded_identity(new_home, setup.root_fd, h->uid, embedded_home);
1737 if (r < 0)
1738 return r;
1739
1740 r = home_extend_embedded_identity(new_home, h, &setup);
1741 if (r < 0)
1742 return r;
1743
1744 r = home_sync_and_statfs(setup.root_fd, NULL);
1745 if (r < 0)
1746 return r;
1747
66aa51f8 1748 r = home_setup_done(&setup);
70a5db58
LP
1749 if (r < 0)
1750 return r;
1751
1752 log_info("Everything completed.");
1753
1754 *ret_home = TAKE_PTR(new_home);
1755 return 1;
1756}
1757
1758static int home_inspect(UserRecord *h, UserRecord **ret_home) {
1759 _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *new_home = NULL;
66aa51f8 1760 _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
7b78db28 1761 _cleanup_(password_cache_free) PasswordCache cache = {};
e1df968b 1762 HomeSetupFlags flags = 0;
70a5db58
LP
1763 int r;
1764
1765 assert(h);
1766 assert(ret_home);
1767
7b78db28 1768 r = user_record_authenticate(h, h, &cache, /* strict_verify= */ false);
70a5db58
LP
1769 if (r < 0)
1770 return r;
1771
e1df968b 1772 r = home_validate_update(h, &setup, &flags);
70a5db58
LP
1773 if (r < 0)
1774 return r;
1775
c00b2ddc 1776 r = home_setup(h, flags, &setup, &cache, &header_home);
70a5db58
LP
1777 if (r < 0)
1778 return r;
1779
7b78db28 1780 r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_ANY, &cache, NULL, &new_home);
70a5db58
LP
1781 if (r < 0)
1782 return r;
1783
1784 r = home_extend_embedded_identity(new_home, h, &setup);
1785 if (r < 0)
1786 return r;
1787
66aa51f8 1788 r = home_setup_done(&setup);
70a5db58
LP
1789 if (r < 0)
1790 return r;
1791
1792 log_info("Everything completed.");
1793
1794 *ret_home = TAKE_PTR(new_home);
1795 return 1;
1796}
1797
1798static int home_lock(UserRecord *h) {
fc032ae1 1799 _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
70a5db58
LP
1800 int r;
1801
1802 assert(h);
1803
1804 if (!h->user_name)
1805 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record incomplete, refusing.");
1806 if (user_record_storage(h) != USER_LUKS)
1807 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Locking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1808
1809 r = user_record_test_home_directory_and_warn(h);
1810 if (r < 0)
1811 return r;
1812 if (r != USER_TEST_MOUNTED)
1813 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC), "Home directory of %s is not mounted, can't lock.", h->user_name);
1814
fc032ae1 1815 r = home_lock_luks(h, &setup);
70a5db58
LP
1816 if (r < 0)
1817 return r;
1818
1819 log_info("Everything completed.");
1820 return 1;
1821}
1822
1823static int home_unlock(UserRecord *h) {
fc032ae1 1824 _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT;
7b78db28 1825 _cleanup_(password_cache_free) PasswordCache cache = {};
70a5db58
LP
1826 int r;
1827
1828 assert(h);
1829
1830 if (!h->user_name)
1831 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record incomplete, refusing.");
1832 if (user_record_storage(h) != USER_LUKS)
1833 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Unlocking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1834
1835 /* Note that we don't check if $HOME is actually mounted, since we want to avoid disk accesses on
1836 * that mount until we have resumed the device. */
1837
7b78db28 1838 r = user_record_authenticate(h, h, &cache, /* strict_verify= */ false);
70a5db58
LP
1839 if (r < 0)
1840 return r;
1841
fc032ae1 1842 r = home_unlock_luks(h, &setup, &cache);
70a5db58
LP
1843 if (r < 0)
1844 return r;
1845
1846 log_info("Everything completed.");
1847 return 1;
1848}
1849
1850static int run(int argc, char *argv[]) {
1851 _cleanup_(user_record_unrefp) UserRecord *home = NULL, *new_home = NULL;
1852 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
5d2a48da 1853 _cleanup_fclose_ FILE *opened_file = NULL;
70a5db58
LP
1854 unsigned line = 0, column = 0;
1855 const char *json_path = NULL;
1856 FILE *json_file;
1857 usec_t start;
1858 int r;
1859
1860 start = now(CLOCK_MONOTONIC);
1861
d2acb93d 1862 log_setup();
70a5db58 1863
30f19400
LP
1864 cryptsetup_enable_logging(NULL);
1865
70a5db58
LP
1866 umask(0022);
1867
1868 if (argc < 2 || argc > 3)
1869 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes one or two arguments.");
1870
1871 if (argc > 2) {
1872 json_path = argv[2];
1873
1874 opened_file = fopen(json_path, "re");
1875 if (!opened_file)
1876 return log_error_errno(errno, "Failed to open %s: %m", json_path);
1877
1878 json_file = opened_file;
1879 } else {
1880 json_path = "<stdin>";
1881 json_file = stdin;
1882 }
1883
1884 r = json_parse_file(json_file, json_path, JSON_PARSE_SENSITIVE, &v, &line, &column);
1885 if (r < 0)
1886 return log_error_errno(r, "[%s:%u:%u] Failed to parse JSON data: %m", json_path, line, column);
1887
1888 home = user_record_new();
1889 if (!home)
1890 return log_oom();
1891
bfc0cc1a 1892 r = user_record_load(home, v, USER_RECORD_LOAD_FULL|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
70a5db58
LP
1893 if (r < 0)
1894 return r;
1895
1896 /* Well known return values of these operations, that systemd-homed knows and converts to proper D-Bus errors:
1897 *
162392b7
ZJS
1898 * EMSGSIZE → file systems of this type cannot be shrunk
1899 * ETXTBSY → file systems of this type can only be shrunk offline
70a5db58
LP
1900 * ERANGE → file system size too small
1901 * ENOLINK → system does not support selected storage backend
1902 * EPROTONOSUPPORT → system does not support selected file system
1903 * ENOTTY → operation not support on this storage
1904 * ESOCKTNOSUPPORT → operation not support on this file system
1905 * ENOKEY → password incorrect (or not sufficient, or not supplied)
87d7893c 1906 * EREMOTEIO → recovery key incorrect (or not sufficeint, or not supplied — only if no passwords defined)
70a5db58 1907 * EBADSLT → similar, but PKCS#11 device is defined and might be able to provide password, if it was plugged in which it is not
7b78db28 1908 * ENOANO → suitable PKCS#11/FIDO2 device found, but PIN is missing to unlock it
70a5db58 1909 * ERFKILL → suitable PKCS#11 device found, but OK to ask for on-device interactive authentication not given
7b78db28 1910 * EMEDIUMTYPE → suitable FIDO2 device found, but OK to ask for user presence not given
17e7561a 1911 * ENOCSI → suitable FIDO2 device found, but OK to ask for user verification not given
7b78db28
LP
1912 * ENOSTR → suitable FIDO2 device found, but user didn't react to action request on token quickly enough
1913 * EOWNERDEAD → suitable PKCS#11/FIDO2 device found, but its PIN is locked
1914 * ENOLCK → suitable PKCS#11/FIDO2 device found, but PIN incorrect
70a5db58
LP
1915 * ETOOMANYREFS → suitable PKCS#11 device found, but PIN incorrect, and only few tries left
1916 * EUCLEAN → suitable PKCS#11 device found, but PIN incorrect, and only one try left
1917 * EBUSY → file system is currently active
1918 * ENOEXEC → file system is currently not active
1919 * ENOSPC → not enough disk space for operation
cbffdcec 1920 * EKEYREVOKED → user record has not suitable hashed password or pkcs#11 entry, we cannot authenticate
2aaf565a 1921 * EADDRINUSE → home image is already used elsewhere (lock taken)
70a5db58
LP
1922 */
1923
1924 if (streq(argv[1], "activate"))
1925 r = home_activate(home, &new_home);
1926 else if (streq(argv[1], "deactivate"))
1927 r = home_deactivate(home, false);
1928 else if (streq(argv[1], "deactivate-force"))
1929 r = home_deactivate(home, true);
1930 else if (streq(argv[1], "create"))
1931 r = home_create(home, &new_home);
1932 else if (streq(argv[1], "remove"))
1933 r = home_remove(home);
1934 else if (streq(argv[1], "update"))
1935 r = home_update(home, &new_home);
d357b80d
LP
1936 else if (streq(argv[1], "resize")) /* Resize on user request */
1937 r = home_resize(home, false, &new_home);
1938 else if (streq(argv[1], "resize-auto")) /* Automatic resize */
1939 r = home_resize(home, true, &new_home);
70a5db58
LP
1940 else if (streq(argv[1], "passwd"))
1941 r = home_passwd(home, &new_home);
1942 else if (streq(argv[1], "inspect"))
1943 r = home_inspect(home, &new_home);
1944 else if (streq(argv[1], "lock"))
1945 r = home_lock(home);
1946 else if (streq(argv[1], "unlock"))
1947 r = home_unlock(home);
1948 else
1949 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb '%s'.", argv[1]);
87d7893c 1950 if (IN_SET(r, -ENOKEY, -EREMOTEIO) && !strv_isempty(home->password) ) { /* There were passwords specified but they were incorrect */
70a5db58
LP
1951 usec_t end, n, d;
1952
1953 /* Make sure bad password replies always take at least 3s, and if longer multiples of 3s, so
1954 * that it's not clear how long we actually needed for our calculations. */
1955 n = now(CLOCK_MONOTONIC);
1956 assert(n >= start);
1957
1958 d = usec_sub_unsigned(n, start);
1959 if (d > BAD_PASSWORD_DELAY_USEC)
1960 end = start + DIV_ROUND_UP(d, BAD_PASSWORD_DELAY_USEC) * BAD_PASSWORD_DELAY_USEC;
1961 else
1962 end = start + BAD_PASSWORD_DELAY_USEC;
1963
1964 if (n < end)
4251512e 1965 (void) usleep_safe(usec_sub_unsigned(end, n));
70a5db58
LP
1966 }
1967 if (r < 0)
1968 return r;
1969
1970 /* We always pass the new record back, regardless if it changed or not. This allows our caller to
1971 * prepare a fresh record, send to us, and only if it works use it without having to keep a local
1972 * copy. */
1973 if (new_home)
1974 json_variant_dump(new_home->json, JSON_FORMAT_NEWLINE, stdout, NULL);
1975
1976 return 0;
1977}
1978
1979DEFINE_MAIN_FUNCTION(run);