1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
9 #include "blockdev-util.h"
10 #include "bus-unit-util.h"
12 #include "chown-recursive.h"
14 #include "cryptsetup-util.h"
16 #include "errno-util.h"
19 #include "filesystems.h"
20 #include "format-util.h"
22 #include "home-util.h"
23 #include "homework-fido2.h"
24 #include "homework-password-cache.h"
25 #include "homework-pkcs11.h"
27 #include "homework-blob.h"
28 #include "homework-cifs.h"
29 #include "homework-directory.h"
30 #include "homework-fscrypt.h"
31 #include "homework-luks.h"
32 #include "homework-mount.h"
33 #include "json-util.h"
34 #include "libcrypt-util.h"
35 #include "loop-util.h"
36 #include "main-func.h"
37 #include "memory-util.h"
38 #include "missing_magic.h"
39 #include "missing_syscall.h"
40 #include "mount-util.h"
41 #include "path-util.h"
42 #include "recovery-key.h"
44 #include "stat-util.h"
45 #include "string-util.h"
47 #include "sync-util.h"
48 #include "time-util.h"
49 #include "tmpfile-util.h"
50 #include "user-record.h"
51 #include "user-record-util.h"
52 #include "user-util.h"
55 /* Make sure a bad password always results in a 3s delay, no matter what */
56 #define BAD_PASSWORD_DELAY_USEC (3 * USEC_PER_SEC)
58 int user_record_authenticate(
64 bool need_password
= false, need_recovery_key
= false, need_token
= false, need_pin
= false,
65 need_protected_authentication_path_permitted
= false, need_user_presence_permitted
= false,
66 need_user_verification_permitted
= false, pin_locked
= false, pin_incorrect
= false,
67 pin_incorrect_few_tries_left
= false, pin_incorrect_one_try_left
= false, token_action_timeout
= false;
74 /* Tries to authenticate a user record with the supplied secrets. i.e. checks whether at least one
75 * supplied plaintext passwords matches a hashed password field of the user record. Or if a
76 * configured PKCS#11 or FIDO2 token is around and can unlock the record.
78 * Note that the 'cache' parameter is both an input and output parameter: it contains lists of
79 * configured, decrypted PKCS#11/FIDO2 passwords. We typically have to call this function multiple
80 * times over the course of an operation (think: on login we authenticate the host user record, the
81 * record embedded in the LUKS record and the one embedded in $HOME). Hence we keep a list of
82 * passwords we already decrypted, so that we don't have to do the (slow and potentially interactive)
83 * PKCS#11/FIDO2 dance for the relevant token again and again.
85 * The 'cache' parameter might also contain the LUKS volume key, loaded from the kernel keyring.
86 * In this case, authentication becomes optional - if a secret section is provided it will be
87 * verified, but if missing then authentication is skipped entirely. Thus, callers should
88 * consider carefully whether it is safe to load the volume key into 'cache' before doing so.
89 * Note that most of the time this is safe, because the home area must be active for the key
90 * to exist in the keyring, and the user would have had to authenticate when activating their
91 * home area; however, for some methods (i.e. ChangePassword, Authenticate) it makes more sense
92 * to force re-authentication. */
94 /* First, let's see if we already have a volume key from the keyring */
95 if (cache
->volume_key
&&
96 sd_json_variant_is_blank_object(sd_json_variant_by_key(secret
->json
, "secret"))) {
97 log_info("LUKS volume key from keyring unlocks user record.");
101 /* Next, let's see if the supplied plain-text passwords work? */
102 r
= user_record_test_password(h
, secret
);
104 need_password
= true;
105 else if (r
== -ENXIO
)
106 log_debug_errno(r
, "User record has no hashed passwords, plaintext passwords not tested.");
108 return log_error_errno(r
, "Failed to validate password of record: %m");
110 log_info("Provided password unlocks user record.");
114 /* Similar, but test against the recovery keys */
115 r
= user_record_test_recovery_key(h
, secret
);
117 need_recovery_key
= true;
118 else if (r
== -ENXIO
)
119 log_debug_errno(r
, "User record has no recovery keys, plaintext passwords not tested against it.");
121 return log_error_errno(r
, "Failed to validate the recovery key of the record: %m");
123 log_info("Provided password is a recovery key that unlocks the user record.");
127 if (need_password
&& need_recovery_key
)
128 log_info("None of the supplied plaintext passwords unlock the user record's hashed passwords or recovery keys.");
129 else if (need_password
)
130 log_info("None of the supplied plaintext passwords unlock the user record's hashed passwords.");
132 log_info("None of the supplied plaintext passwords unlock the user record's hashed recovery keys.");
134 /* Next, test cached PKCS#11 passwords */
135 FOREACH_ARRAY(i
, h
->pkcs11_encrypted_key
, h
->n_pkcs11_encrypted_key
)
136 STRV_FOREACH(pp
, cache
->pkcs11_passwords
) {
137 r
= test_password_one(i
->hashed_password
, *pp
);
139 return log_error_errno(r
, "Failed to check supplied PKCS#11 password: %m");
141 log_info("Previously acquired PKCS#11 password unlocks user record.");
146 /* Next, test cached FIDO2 passwords */
147 FOREACH_ARRAY(i
, h
->fido2_hmac_salt
, h
->n_fido2_hmac_salt
)
148 /* See if any of the previously calculated passwords work */
149 STRV_FOREACH(pp
, cache
->fido2_passwords
) {
150 r
= test_password_one(i
->hashed_password
, *pp
);
152 return log_error_errno(r
, "Failed to check supplied FIDO2 password: %m");
154 log_info("Previously acquired FIDO2 password unlocks user record.");
159 /* Next, let's see if any of the PKCS#11 security tokens are plugged in and help us */
160 FOREACH_ARRAY(i
, h
->pkcs11_encrypted_key
, h
->n_pkcs11_encrypted_key
) {
162 _cleanup_(pkcs11_callback_data_release
) struct pkcs11_callback_data data
= {
168 r
= pkcs11_find_token(data
.encrypted_key
->uri
, pkcs11_callback
, &data
);
177 need_protected_authentication_path_permitted
= true;
183 pin_incorrect
= true;
186 pin_incorrect
= pin_incorrect_few_tries_left
= true;
189 pin_incorrect
= pin_incorrect_few_tries_left
= pin_incorrect_one_try_left
= true;
195 r
= test_password_one(data
.encrypted_key
->hashed_password
, data
.decrypted_password
);
197 return log_error_errno(r
, "Failed to test PKCS#11 password: %m");
199 return log_error_errno(SYNTHETIC_ERRNO(EPERM
),
200 "Configured PKCS#11 security token %s does not decrypt encrypted key correctly.",
201 data
.encrypted_key
->uri
);
203 log_info("Decrypted password from PKCS#11 security token %s unlocks user record.", data
.encrypted_key
->uri
);
205 r
= strv_extend(&cache
->pkcs11_passwords
, data
.decrypted_password
);
217 /* Next, let's see if any of the FIDO2 security tokens are plugged in and help us */
218 FOREACH_ARRAY(i
, h
->fido2_hmac_salt
, h
->n_fido2_hmac_salt
) {
220 _cleanup_(erase_and_freep
) char *decrypted_password
= NULL
;
222 r
= fido2_use_token(h
, secret
, i
, &decrypted_password
);
234 pin_incorrect
= true;
237 need_user_presence_permitted
= true;
240 need_user_verification_permitted
= true;
243 token_action_timeout
= true;
249 r
= test_password_one(i
->hashed_password
, decrypted_password
);
251 return log_error_errno(r
, "Failed to test FIDO2 password: %m");
253 return log_error_errno(SYNTHETIC_ERRNO(EPERM
),
254 "Configured FIDO2 security token does not decrypt encrypted key correctly.");
256 log_info("Decrypted password from FIDO2 security token unlocks user record.");
258 r
= strv_extend(&cache
->fido2_passwords
, decrypted_password
);
270 /* Ordered by "relevance", i.e. the most "important" or "interesting" error condition is returned. */
271 if (pin_incorrect_one_try_left
)
273 if (pin_incorrect_few_tries_left
)
274 return -ETOOMANYREFS
;
279 if (token_action_timeout
)
281 if (need_protected_authentication_path_permitted
)
283 if (need_user_presence_permitted
)
285 if (need_user_verification_permitted
)
293 if (need_recovery_key
)
296 /* Hmm, this means neither PCKS#11/FIDO2 nor classic hashed passwords or recovery keys were supplied,
297 * we cannot authenticate this reasonably */
299 return log_debug_errno(SYNTHETIC_ERRNO(EKEYREVOKED
),
300 "No hashed passwords, no recovery keys and no PKCS#11/FIDO2 tokens defined, cannot authenticate user record, refusing.");
302 /* If strict verification is off this means we are possibly in the case where we encountered an
303 * unfixated record, i.e. a synthetic one that accordingly lacks any authentication data. In this
304 * case, allow the authentication to pass for now, so that the second (or third) authentication level
305 * (the ones of the user record in the LUKS header or inside the home directory) will then catch
306 * invalid passwords. The second/third authentication always runs in strict verification mode. */
307 log_debug("No hashed passwords, not recovery keys and no PKCS#11 tokens defined in record, cannot authenticate user record. "
308 "Deferring to embedded user record.");
312 static void drop_caches_now(void) {
315 /* Drop file system caches now. See https://docs.kernel.org/admin-guide/sysctl/vm.html
316 * for details. We write "3" into /proc/sys/vm/drop_caches to ensure dentries/inodes are flushed, but
319 r
= write_string_file("/proc/sys/vm/drop_caches", "3\n", WRITE_STRING_FILE_DISABLE_BUFFER
);
321 log_warning_errno(r
, "Failed to drop caches, ignoring: %m");
323 log_debug("Dropped caches.");
326 int home_setup_undo_mount(HomeSetup
*setup
, int level
) {
331 if (!setup
->undo_mount
)
334 r
= umount_recursive(HOME_RUNTIME_WORK_DIR
, 0);
336 if (level
>= LOG_DEBUG
) /* umount_recursive() does debug level logging anyway, no need to
337 * repeat that here */
340 /* If a higher log level is requested, the generate a non-debug message here too. */
341 return log_full_errno(level
, r
, "Failed to unmount mount tree below %s: %m", HOME_RUNTIME_WORK_DIR
);
344 setup
->undo_mount
= false;
348 int home_setup_undo_dm(HomeSetup
*setup
, int level
) {
353 if (setup
->undo_dm
) {
354 assert(setup
->crypt_device
);
355 assert(setup
->dm_name
);
357 r
= sym_crypt_deactivate_by_name(setup
->crypt_device
, setup
->dm_name
, 0);
359 return log_full_errno(level
, r
, "Failed to deactivate LUKS device: %m");
361 /* In case the device was already remove asynchronously by an early unmount via the deferred
362 * remove logic, let's wait for it */
363 (void) wait_for_block_device_gone(setup
, USEC_PER_SEC
* 30);
365 setup
->undo_dm
= false;
370 if (setup
->crypt_device
) {
371 sym_crypt_free(setup
->crypt_device
);
372 setup
->crypt_device
= NULL
;
378 int keyring_unlink(key_serial_t k
) {
380 if (k
== -1) /* already invalidated? */
383 if (keyctl(KEYCTL_UNLINK
, k
, KEY_SPEC_SESSION_KEYRING
, 0, 0) < 0)
384 log_debug_errno(errno
, "Failed to unlink key from session kernel keyring, ignoring: %m");
386 return -1; /* Always return the key_serial_t value for "invalid" */
389 static int keyring_flush(UserRecord
*h
) {
390 _cleanup_free_
char *name
= NULL
;
395 if (user_record_storage(h
) == USER_FSCRYPT
)
396 (void) home_flush_keyring_fscrypt(h
);
398 name
= strjoin("homework-user-", h
->user_name
);
402 serial
= keyctl(KEYCTL_SEARCH
, (unsigned long) KEY_SPEC_SESSION_KEYRING
, (unsigned long) "user", (unsigned long) name
, 0);
404 return log_debug_errno(errno
, "Failed to find kernel keyring entry for user, ignoring: %m");
406 return keyring_unlink(serial
);
409 int home_setup_done(HomeSetup
*setup
) {
414 if (setup
->root_fd
>= 0) {
415 if (setup
->do_offline_fitrim
) {
416 q
= run_fitrim(setup
->root_fd
);
421 if (syncfs(setup
->root_fd
) < 0)
422 log_debug_errno(errno
, "Failed to synchronize home directory, ignoring: %m");
424 setup
->root_fd
= safe_close(setup
->root_fd
);
427 q
= home_setup_undo_mount(setup
, LOG_DEBUG
);
431 q
= home_setup_undo_dm(setup
, LOG_DEBUG
);
435 if (setup
->image_fd
>= 0) {
436 if (setup
->do_offline_fallocate
) {
437 q
= run_fallocate(setup
->image_fd
, NULL
);
442 if (setup
->do_mark_clean
) {
443 q
= run_mark_dirty(setup
->image_fd
, false);
448 setup
->image_fd
= safe_close(setup
->image_fd
);
451 if (setup
->temporary_image_path
) {
452 if (unlink(setup
->temporary_image_path
) < 0)
453 log_debug_errno(errno
, "Failed to remove temporary image file '%s', ignoring: %m",
454 setup
->temporary_image_path
);
456 setup
->temporary_image_path
= mfree(setup
->temporary_image_path
);
459 setup
->key_serial
= keyring_unlink(setup
->key_serial
);
461 setup
->undo_mount
= false;
462 setup
->undo_dm
= false;
463 setup
->do_offline_fitrim
= false;
464 setup
->do_offline_fallocate
= false;
465 setup
->do_mark_clean
= false;
467 setup
->dm_name
= mfree(setup
->dm_name
);
468 setup
->dm_node
= mfree(setup
->dm_node
);
470 setup
->loop
= loop_device_unref(setup
->loop
);
472 setup
->volume_key
= erase_and_free(setup
->volume_key
);
473 setup
->volume_key_size
= 0;
475 if (setup
->do_drop_caches
)
478 setup
->mount_suffix
= mfree(setup
->mount_suffix
);
485 HomeSetupFlags flags
,
487 PasswordCache
*cache
,
488 UserRecord
**ret_header_home
) {
494 assert(!setup
->loop
);
495 assert(!setup
->crypt_device
);
496 assert(setup
->root_fd
< 0);
497 assert(!setup
->undo_dm
);
498 assert(!setup
->undo_mount
);
500 /* Makes a home directory accessible (through the root_fd file descriptor, not by path!). */
502 if (!FLAGS_SET(flags
, HOME_SETUP_ALREADY_ACTIVATED
)) /* If we set up the directory, we should also drop caches once we are done */
503 setup
->do_drop_caches
= setup
->do_drop_caches
|| user_record_drop_caches(h
);
505 switch (user_record_storage(h
)) {
508 return home_setup_luks(h
, flags
, NULL
, setup
, cache
, ret_header_home
);
512 r
= home_setup_directory(h
, setup
);
516 r
= home_setup_fscrypt(h
, setup
, cache
);
520 r
= home_setup_cifs(h
, flags
, setup
);
524 return log_error_errno(SYNTHETIC_ERRNO(ENOLINK
), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
531 *ret_header_home
= NULL
;
536 int home_sync_and_statfs(int root_fd
, struct statfs
*ret
) {
537 assert(root_fd
>= 0);
539 /* Let's sync this to disk, so that the disk space reported by fstatfs() below is accurate (for file
540 * systems such as btrfs where this is determined lazily). */
542 if (syncfs(root_fd
) < 0)
543 return log_error_errno(errno
, "Failed to synchronize file system: %m");
546 if (fstatfs(root_fd
, ret
) < 0)
547 return log_error_errno(errno
, "Failed to statfs() file system: %m");
549 log_info("Synchronized disk.");
554 static int read_identity_file(int root_fd
, sd_json_variant
**ret
) {
555 _cleanup_fclose_
FILE *identity_file
= NULL
;
556 _cleanup_close_
int identity_fd
= -EBADF
;
559 assert(root_fd
>= 0);
562 identity_fd
= openat(root_fd
, ".identity", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
|O_NONBLOCK
);
564 return log_error_errno(errno
, "Failed to open .identity file in home directory: %m");
566 r
= fd_verify_regular(identity_fd
);
568 return log_error_errno(r
, "Embedded identity file is not a regular file, refusing: %m");
570 identity_file
= take_fdopen(&identity_fd
, "r");
574 unsigned line
= 0, column
= 0;
575 r
= sd_json_parse_file(identity_file
, ".identity", SD_JSON_PARSE_SENSITIVE
, ret
, &line
, &column
);
577 return log_error_errno(r
, "[.identity:%u:%u] Failed to parse JSON data: %m", line
, column
);
579 log_info("Read embedded .identity file.");
584 static int write_identity_file(int root_fd
, sd_json_variant
*v
, uid_t uid
) {
585 _cleanup_(sd_json_variant_unrefp
) sd_json_variant
*normalized
= NULL
;
586 _cleanup_fclose_
FILE *identity_file
= NULL
;
587 _cleanup_close_
int identity_fd
= -EBADF
;
588 _cleanup_free_
char *fn
= NULL
;
591 assert(root_fd
>= 0);
594 normalized
= sd_json_variant_ref(v
);
596 r
= sd_json_variant_normalize(&normalized
);
598 log_warning_errno(r
, "Failed to normalize user record, ignoring: %m");
600 r
= tempfn_random(".identity", NULL
, &fn
);
604 identity_fd
= openat(root_fd
, fn
, O_WRONLY
|O_CREAT
|O_EXCL
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
, 0600);
606 return log_error_errno(errno
, "Failed to create .identity file in home directory: %m");
608 identity_file
= take_fdopen(&identity_fd
, "w");
609 if (!identity_file
) {
614 sd_json_variant_dump(normalized
, SD_JSON_FORMAT_PRETTY
, identity_file
, NULL
);
616 r
= fflush_and_check(identity_file
);
618 log_error_errno(r
, "Failed to write .identity file: %m");
622 if (fchown(fileno(identity_file
), uid
, uid
) < 0) {
623 r
= log_error_errno(errno
, "Failed to change ownership of identity file: %m");
627 if (renameat(root_fd
, fn
, root_fd
, ".identity") < 0) {
628 r
= log_error_errno(errno
, "Failed to move identity file into place: %m");
632 log_info("Wrote embedded .identity file.");
637 (void) unlinkat(root_fd
, fn
, 0);
641 int home_load_embedded_identity(
644 UserRecord
*header_home
,
645 UserReconcileMode mode
,
646 PasswordCache
*cache
,
647 UserRecord
**ret_embedded_home
,
648 UserRecord
**ret_new_home
) {
650 _cleanup_(user_record_unrefp
) UserRecord
*embedded_home
= NULL
, *intermediate_home
= NULL
, *new_home
= NULL
;
651 _cleanup_(sd_json_variant_unrefp
) sd_json_variant
*v
= NULL
;
655 assert(root_fd
>= 0);
657 r
= read_identity_file(root_fd
, &v
);
661 embedded_home
= user_record_new();
665 r
= user_record_load(embedded_home
, v
, USER_RECORD_LOAD_EMBEDDED
|USER_RECORD_PERMISSIVE
);
669 if (!user_record_compatible(h
, embedded_home
))
670 return log_error_errno(SYNTHETIC_ERRNO(EREMCHG
), "Embedded home record not compatible with host record, refusing.");
672 /* Insist that credentials the user supplies also unlocks any embedded records. */
673 r
= user_record_authenticate(embedded_home
, h
, cache
, /* strict_verify= */ true);
676 assert(r
> 0); /* Insist that a password was verified */
678 /* At this point we have three records to deal with:
680 * · The record we got passed from the host
681 * · The record included in the LUKS header (only if LUKS is used)
682 * · The record in the home directory itself (~/.identity)
684 * Now we have to reconcile all three, and let the newest one win. */
687 /* Note we relax the requirements here. Instead of insisting that the host record is strictly
688 * newer, let's also be OK if its equally new. If it is, we'll however insist that the
689 * embedded record must be newer, so that we update at least one of the two. */
691 r
= user_record_reconcile(h
, header_home
, mode
== USER_RECONCILE_REQUIRE_NEWER
? USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL
: mode
, &intermediate_home
);
692 if (r
== -EREMCHG
) /* this was supposed to be checked earlier already, but let's check this again */
693 return log_error_errno(r
, "Identity stored on host and in header don't match, refusing.");
695 return log_error_errno(r
, "Embedded identity record is newer than supplied record, refusing.");
697 return log_error_errno(r
, "Failed to reconcile host and header identities: %m");
698 if (r
== USER_RECONCILE_EMBEDDED_WON
)
699 log_info("Reconciling header user identity completed (header version was newer).");
700 else if (r
== USER_RECONCILE_HOST_WON
) {
701 log_info("Reconciling header user identity completed (host version was newer).");
703 if (mode
== USER_RECONCILE_REQUIRE_NEWER
) /* Host version is newer than the header
704 * version, hence we'll update
705 * something. This means we can relax the
706 * requirements on the embedded
708 mode
= USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL
;
710 assert(r
== USER_RECONCILE_IDENTICAL
);
711 log_info("Reconciling user identities completed (host and header version were identical).");
714 h
= intermediate_home
;
717 r
= user_record_reconcile(h
, embedded_home
, mode
, &new_home
);
719 return log_error_errno(r
, "Identity stored on host and in home don't match, refusing.");
721 return log_error_errno(r
, "Embedded identity record is equally new or newer than supplied record, refusing.");
723 return log_error_errno(r
, "Failed to reconcile host and embedded identities: %m");
724 if (r
== USER_RECONCILE_EMBEDDED_WON
)
725 log_info("Reconciling embedded user identity completed (embedded version was newer).");
726 else if (r
== USER_RECONCILE_HOST_WON
)
727 log_info("Reconciling embedded user identity completed (host version was newer).");
729 assert(r
== USER_RECONCILE_IDENTICAL
);
730 log_info("Reconciling embedded user identity completed (host and embedded version were identical).");
733 if (ret_embedded_home
)
734 *ret_embedded_home
= TAKE_PTR(embedded_home
);
737 *ret_new_home
= TAKE_PTR(new_home
);
739 return r
; /* We pass along who won the reconciliation */
742 int home_store_embedded_identity(UserRecord
*h
, int root_fd
, UserRecord
*old_home
) {
743 _cleanup_(user_record_unrefp
) UserRecord
*embedded
= NULL
;
747 assert(root_fd
>= 0);
749 r
= user_record_clone(h
, USER_RECORD_EXTRACT_EMBEDDED
|USER_RECORD_PERMISSIVE
, &embedded
);
751 return log_error_errno(r
, "Failed to determine new embedded record: %m");
753 if (old_home
&& user_record_equal(old_home
, embedded
)) {
754 log_debug("Not updating embedded home record.");
758 /* The identity has changed, let's update it in the image */
759 r
= write_identity_file(root_fd
, embedded
->json
, h
->uid
);
766 static const char *file_system_type_fd(int fd
) {
771 if (fstatfs(fd
, &sfs
) < 0) {
772 log_debug_errno(errno
, "Failed to statfs(): %m");
776 return fs_type_to_string(sfs
.f_type
);
779 int home_extend_embedded_identity(UserRecord
*h
, UserRecord
*used
, HomeSetup
*setup
) {
786 r
= user_record_add_binding(
788 user_record_storage(used
),
789 user_record_image_path(used
),
790 setup
->found_partition_uuid
,
791 setup
->found_luks_uuid
,
792 setup
->found_fs_uuid
,
793 setup
->crypt_device
? sym_crypt_get_cipher(setup
->crypt_device
) : NULL
,
794 setup
->crypt_device
? sym_crypt_get_cipher_mode(setup
->crypt_device
) : NULL
,
795 setup
->crypt_device
? luks_volume_key_size_convert(setup
->crypt_device
) : UINT64_MAX
,
796 file_system_type_fd(setup
->root_fd
),
797 user_record_home_directory(used
),
801 return log_error_errno(r
, "Failed to update binding in record: %m");
806 static int chown_recursive_directory(int root_fd
, uid_t uid
) {
809 assert(root_fd
>= 0);
810 assert(uid_is_valid(uid
));
812 r
= fd_chown_recursive(root_fd
, uid
, (gid_t
) uid
, 0777);
814 return log_error_errno(r
, "Failed to change ownership of files and directories: %m");
816 log_info("Recursive changing of ownership not necessary, skipped.");
818 log_info("Recursive changing of ownership completed.");
823 int home_maybe_shift_uid(
825 HomeSetupFlags flags
,
828 _cleanup_close_
int mount_fd
= -EBADF
;
833 assert(setup
->root_fd
>= 0);
835 /* If the home dir is already activated, then the UID shift is already applied. */
836 if (FLAGS_SET(flags
, HOME_SETUP_ALREADY_ACTIVATED
))
839 if (fstat(setup
->root_fd
, &st
) < 0)
840 return log_error_errno(errno
, "Failed to stat() home directory: %m");
842 /* Let's shift UIDs of this mount. Hopefully this makes the later chowning unnecessary. (Note that we
843 * also prefer to do UID mapping even if the UID already matches our goal UID. That's because we want
844 * to leave UIDs in the homed managed range unmapped.) */
845 (void) home_shift_uid(setup
->root_fd
, NULL
, st
.st_uid
, h
->uid
, &mount_fd
);
847 /* If this worked, then we'll have a reference to the mount now, which we can also use like an O_PATH
848 * fd to the new dir. Let's convert it into a proper O_DIRECTORY fd. */
850 safe_close(setup
->root_fd
);
852 setup
->root_fd
= fd_reopen(mount_fd
, O_RDONLY
|O_CLOEXEC
|O_DIRECTORY
);
853 if (setup
->root_fd
< 0)
854 return log_error_errno(setup
->root_fd
, "Failed to convert mount fd into regular directory fd: %m");
862 HomeSetupFlags flags
,
864 UserRecord
*header_home
,
865 PasswordCache
*cache
,
866 struct statfs
*ret_statfs
,
867 UserRecord
**ret_new_home
) {
869 _cleanup_(user_record_unrefp
) UserRecord
*embedded_home
= NULL
, *new_home
= NULL
;
874 assert(ret_new_home
);
876 /* When activating a home directory, does the identity work: loads the identity from the $HOME
877 * directory, reconciles it with our idea, chown()s everything. */
879 reconciled
= home_load_embedded_identity(h
, setup
->root_fd
, header_home
, USER_RECONCILE_ANY
, cache
, &embedded_home
, &new_home
);
883 r
= home_maybe_shift_uid(h
, flags
, setup
);
887 r
= home_store_header_identity_luks(new_home
, setup
, header_home
);
891 r
= home_store_embedded_identity(new_home
, setup
->root_fd
, embedded_home
);
895 r
= home_reconcile_blob_dirs(new_home
, setup
->root_fd
, reconciled
);
899 r
= chown_recursive_directory(setup
->root_fd
, h
->uid
);
903 r
= home_sync_and_statfs(setup
->root_fd
, ret_statfs
);
907 *ret_new_home
= TAKE_PTR(new_home
);
911 static int home_activate(UserRecord
*h
, UserRecord
**ret_home
) {
912 _cleanup_(home_setup_done
) HomeSetup setup
= HOME_SETUP_INIT
;
913 _cleanup_(user_record_unrefp
) UserRecord
*new_home
= NULL
;
914 _cleanup_(password_cache_free
) PasswordCache cache
= {};
915 HomeSetupFlags flags
= 0;
921 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks user name, refusing.");
922 if (!uid_is_valid(h
->uid
))
923 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks UID, refusing.");
924 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
925 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Activating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
927 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ false);
931 r
= user_record_test_home_directory_and_warn(h
);
934 if (r
== USER_TEST_MOUNTED
)
935 return log_error_errno(SYNTHETIC_ERRNO(EALREADY
), "Home directory %s is already mounted, refusing.", user_record_home_directory(h
));
937 r
= user_record_test_image_path_and_warn(h
);
940 if (r
== USER_TEST_ABSENT
)
941 return log_error_errno(SYNTHETIC_ERRNO(ENETUNREACH
), "Image path %s is missing, refusing.", user_record_image_path(h
));
943 switch (user_record_storage(h
)) {
946 r
= home_activate_luks(h
, flags
, &setup
, &cache
, &new_home
);
952 r
= home_activate_directory(h
, flags
, &setup
, &cache
, &new_home
);
956 r
= home_activate_cifs(h
, flags
, &setup
, &cache
, &new_home
);
960 assert_not_reached();
965 /* Note that the returned object might either be a reference to an updated version of the existing
966 * home object, or a reference to a newly allocated home object. The caller has to be able to deal
967 * with both, and consider the old object out-of-date. */
968 if (user_record_equal(h
, new_home
)) {
970 return 0; /* no identity change */
973 *ret_home
= TAKE_PTR(new_home
);
974 return 1; /* identity updated */
977 static int home_deactivate(UserRecord
*h
, bool force
) {
978 _cleanup_(home_setup_done
) HomeSetup setup
= HOME_SETUP_INIT
;
979 _cleanup_(password_cache_free
) PasswordCache cache
= {};
986 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record incomplete, refusing.");
987 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
988 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Deactivating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
990 r
= user_record_test_home_directory_and_warn(h
);
993 if (r
== USER_TEST_MOUNTED
) {
994 /* Before we do anything, let's move the home mount away. */
995 r
= home_unshare_and_mkdir();
999 r
= mount_nofollow_verbose(LOG_ERR
, user_record_home_directory(h
), HOME_RUNTIME_WORK_DIR
, NULL
, MS_BIND
, NULL
);
1003 setup
.undo_mount
= true; /* remember to unmount the new bind mount from HOME_RUNTIME_WORK_DIR */
1005 /* Let's explicitly open the new root fs, using the moved path */
1006 setup
.root_fd
= open(HOME_RUNTIME_WORK_DIR
, O_RDONLY
|O_DIRECTORY
|O_CLOEXEC
);
1007 if (setup
.root_fd
< 0)
1008 return log_error_errno(errno
, "Failed to open moved home directory: %m");
1010 /* Now get rid of the home at its original place (we only keep the bind mount we created above) */
1011 r
= umount_verbose(LOG_ERR
, user_record_home_directory(h
), UMOUNT_NOFOLLOW
| (force
? MNT_FORCE
|MNT_DETACH
: 0));
1015 if (user_record_storage(h
) == USER_LUKS
) {
1016 /* Automatically shrink on logout if that's enabled. To be able to shrink we need the
1017 * keys to the device. */
1018 password_cache_load_keyring(h
, &cache
);
1019 (void) home_trim_luks(h
, &setup
);
1022 /* Sync explicitly, so that the drop caches logic below can work as documented */
1023 if (syncfs(setup
.root_fd
) < 0)
1024 log_debug_errno(errno
, "Failed to synchronize home directory, ignoring: %m");
1026 log_info("Syncing completed.");
1028 if (user_record_storage(h
) == USER_LUKS
)
1029 (void) home_auto_shrink_luks(h
, &setup
, &cache
);
1031 setup
.root_fd
= safe_close(setup
.root_fd
);
1033 /* Now get rid of the bind mount, too */
1034 r
= umount_verbose(LOG_ERR
, HOME_RUNTIME_WORK_DIR
, UMOUNT_NOFOLLOW
| (force
? MNT_FORCE
|MNT_DETACH
: 0));
1038 setup
.undo_mount
= false; /* Remember that the bind mount doesn't need to be unmounted anymore */
1040 if (user_record_drop_caches(h
))
1041 setup
.do_drop_caches
= true;
1043 log_info("Unmounting completed.");
1046 log_info("Directory %s is already unmounted.", user_record_home_directory(h
));
1048 if (user_record_storage(h
) == USER_LUKS
) {
1049 r
= home_deactivate_luks(h
, &setup
);
1056 /* Explicitly flush any per-user key from the keyring */
1057 (void) keyring_flush(h
);
1060 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC
), "Home is not active.");
1062 if (setup
.do_drop_caches
) {
1063 setup
.do_drop_caches
= false;
1067 log_info("Everything completed.");
1071 static int copy_skel(UserRecord
*h
, int root_fd
, const char *skel
) {
1072 _cleanup_close_
int skel_fd
= -EBADF
;
1076 assert(root_fd
>= 0);
1078 r
= chase(skel
, /* root= */ NULL
, CHASE_MUST_BE_DIRECTORY
, /* ret_path= */ NULL
, &skel_fd
);
1080 log_info("Skeleton directory %s missing, ignoring.", skel
);
1085 skel_fd
, /* from= */ NULL
,
1087 h
->uid
, user_record_gid(h
),
1088 COPY_MERGE
|COPY_REPLACE
,
1089 /* denylist= */ NULL
,
1090 /* subvolumes= */ NULL
);
1092 return log_error_errno(r
, "Failed to copy in %s: %m", skel
);
1094 log_info("Copying in %s completed.", skel
);
1098 static int change_access_mode(int root_fd
, mode_t m
) {
1099 assert(root_fd
>= 0);
1101 if (fchmod(root_fd
, m
) < 0)
1102 return log_error_errno(errno
, "Failed to change access mode of top-level directory: %m");
1104 log_info("Changed top-level directory access mode to 0%o.", m
);
1108 int home_populate(UserRecord
*h
, int dir_fd
) {
1112 assert(dir_fd
>= 0);
1114 r
= copy_skel(h
, dir_fd
, user_record_skeleton_directory(h
));
1118 r
= home_store_embedded_identity(h
, dir_fd
, NULL
);
1122 r
= home_reconcile_blob_dirs(h
, dir_fd
, USER_RECONCILE_HOST_WON
);
1126 r
= chown_recursive_directory(dir_fd
, h
->uid
);
1130 r
= change_access_mode(dir_fd
, user_record_access_mode(h
));
1137 static int user_record_compile_effective_passwords(
1139 PasswordCache
*cache
,
1140 char ***ret_effective_passwords
) {
1142 _cleanup_strv_free_erase_
char **effective
= NULL
;
1148 /* We insist on at least one classic hashed password to be defined in addition to any PKCS#11 one, as
1149 * a safe fallback, but also to simplify the password changing algorithm: there we require providing
1150 * the old literal password only (and do not care for the old PKCS#11 token) */
1152 if (strv_isempty(h
->hashed_password
))
1153 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
1154 "User record has no hashed passwords, refusing.");
1156 /* Generates the list of plaintext passwords to propagate to LUKS/fscrypt devices, and checks whether
1157 * we have a plaintext password for each hashed one. If we are missing one we'll fail, since we
1158 * couldn't sync fscrypt/LUKS to the login account properly. */
1160 STRV_FOREACH(i
, h
->hashed_password
) {
1163 log_debug("Looking for plaintext password for: %s", *i
);
1165 /* Let's scan all provided plaintext passwords */
1166 STRV_FOREACH(j
, h
->password
) {
1167 r
= test_password_one(*i
, *j
);
1169 return log_error_errno(r
, "Failed to test plaintext password: %m");
1171 if (ret_effective_passwords
) {
1172 r
= strv_extend(&effective
, *j
);
1177 log_debug("Found literal plaintext password.");
1184 return log_error_errno(SYNTHETIC_ERRNO(ENOKEY
), "Missing plaintext password for defined hashed password");
1187 FOREACH_ARRAY(i
, h
->recovery_key
, h
->n_recovery_key
) {
1190 log_debug("Looking for plaintext recovery key for: %s", i
->hashed_password
);
1192 STRV_FOREACH(j
, h
->password
) {
1193 _cleanup_(erase_and_freep
) char *mangled
= NULL
;
1196 if (streq(i
->type
, "modhex64")) {
1197 r
= normalize_recovery_key(*j
, &mangled
);
1198 if (r
== -EINVAL
) /* Not properly formatted, probably a regular password. */
1201 return log_error_errno(r
, "Failed to normalize recovery key: %m");
1207 r
= test_password_one(i
->hashed_password
, p
);
1209 return log_error_errno(r
, "Failed to test plaintext recovery key: %m");
1211 if (ret_effective_passwords
) {
1212 r
= strv_extend(&effective
, p
);
1217 log_debug("Found plaintext recovery key.");
1224 return log_error_errno(SYNTHETIC_ERRNO(EREMOTEIO
),
1225 "Missing plaintext recovery key for defined recovery key.");
1228 FOREACH_ARRAY(i
, h
->pkcs11_encrypted_key
, h
->n_pkcs11_encrypted_key
) {
1230 _cleanup_(pkcs11_callback_data_release
) struct pkcs11_callback_data data
= {
1236 r
= pkcs11_find_token(data
.encrypted_key
->uri
, pkcs11_callback
, &data
);
1242 r
= test_password_one(data
.encrypted_key
->hashed_password
, data
.decrypted_password
);
1244 return log_error_errno(r
, "Failed to test PKCS#11 password: %m");
1246 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Decrypted password from token is not correct, refusing.");
1248 if (ret_effective_passwords
) {
1249 r
= strv_extend(&effective
, data
.decrypted_password
);
1254 r
= strv_extend(&cache
->pkcs11_passwords
, data
.decrypted_password
);
1262 FOREACH_ARRAY(i
, h
->fido2_hmac_salt
, h
->n_fido2_hmac_salt
) {
1264 _cleanup_(erase_and_freep
) char *decrypted_password
= NULL
;
1266 r
= fido2_use_token(h
, h
, i
, &decrypted_password
);
1270 r
= test_password_one(i
->hashed_password
, decrypted_password
);
1272 return log_error_errno(r
, "Failed to test FIDO2 password: %m");
1274 return log_error_errno(SYNTHETIC_ERRNO(EPERM
),
1275 "Decrypted password from token is not correct, refusing.");
1277 if (ret_effective_passwords
) {
1278 r
= strv_extend(&effective
, decrypted_password
);
1283 r
= strv_extend(&cache
->fido2_passwords
, decrypted_password
);
1291 if (ret_effective_passwords
)
1292 *ret_effective_passwords
= TAKE_PTR(effective
);
1297 static int determine_default_storage(UserStorage
*ret
) {
1298 UserStorage storage
= _USER_STORAGE_INVALID
;
1304 /* homed tells us via an environment variable which default storage to use */
1305 e
= getenv("SYSTEMD_HOME_DEFAULT_STORAGE");
1307 storage
= user_storage_from_string(e
);
1309 log_warning("$SYSTEMD_HOME_DEFAULT_STORAGE set to invalid storage type, ignoring: %s", e
);
1311 log_info("Using configured default storage '%s'.", user_storage_to_string(storage
));
1317 /* When neither user nor admin specified the storage type to use, fix it to be LUKS — unless we run
1318 * in a container where loopback devices and LUKS/DM are not available. Also, if /home is encrypted
1319 * anyway, let's avoid duplicate encryption. Note that we typically default to the assumption of
1320 * "classic" storage for most operations. However, if we create a new home, then let's user LUKS if
1321 * nothing is specified. */
1323 r
= detect_container();
1325 return log_error_errno(r
, "Failed to determine whether we are in a container: %m");
1327 r
= path_is_encrypted(get_home_root());
1329 log_info("%s is encrypted, not using '%s' storage, in order to avoid double encryption.", get_home_root(), user_storage_to_string(USER_LUKS
));
1332 log_warning_errno(r
, "Failed to determine if %s is encrypted, ignoring: %m", get_home_root());
1334 r
= dlopen_cryptsetup();
1336 log_info("Not using '%s' storage, since libcryptsetup could not be loaded.", user_storage_to_string(USER_LUKS
));
1338 log_info("Using automatic default storage of '%s'.", user_storage_to_string(USER_LUKS
));
1344 log_info("Running in container, not using '%s' storage.", user_storage_to_string(USER_LUKS
));
1346 r
= path_is_fs_type(get_home_root(), BTRFS_SUPER_MAGIC
);
1348 log_warning_errno(r
, "Failed to determine file system of %s, ignoring: %m", get_home_root());
1350 log_info("%s is on btrfs, using '%s' as storage.", get_home_root(), user_storage_to_string(USER_SUBVOLUME
));
1351 *ret
= USER_SUBVOLUME
;
1353 log_info("%s is on simple file system, using '%s' as storage.", get_home_root(), user_storage_to_string(USER_DIRECTORY
));
1354 *ret
= USER_DIRECTORY
;
1360 static int home_create(UserRecord
*h
, Hashmap
*blobs
, UserRecord
**ret_home
) {
1361 _cleanup_strv_free_erase_
char **effective_passwords
= NULL
;
1362 _cleanup_(home_setup_done
) HomeSetup setup
= HOME_SETUP_INIT
;
1363 _cleanup_(user_record_unrefp
) UserRecord
*new_home
= NULL
;
1364 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1365 UserStorage new_storage
= _USER_STORAGE_INVALID
;
1366 const char *new_fs
= NULL
;
1372 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks name, refusing.");
1373 if (!uid_is_valid(h
->uid
))
1374 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks UID, refusing.");
1376 r
= user_record_compile_effective_passwords(h
, &cache
, &effective_passwords
);
1380 r
= user_record_test_home_directory_and_warn(h
);
1383 if (r
!= USER_TEST_ABSENT
)
1384 return log_error_errno(SYNTHETIC_ERRNO(EEXIST
), "Home directory %s already exists, refusing.", user_record_home_directory(h
));
1386 if (h
->storage
< 0) {
1387 r
= determine_default_storage(&new_storage
);
1392 if ((h
->storage
== USER_LUKS
||
1393 (h
->storage
< 0 && new_storage
== USER_LUKS
)) &&
1394 !h
->file_system_type
)
1395 new_fs
= getenv("SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE");
1397 if (new_storage
>= 0 || new_fs
) {
1398 r
= user_record_add_binding(
1413 return log_error_errno(r
, "Failed to change storage type to LUKS: %m");
1416 r
= user_record_test_image_path_and_warn(h
);
1419 if (!IN_SET(r
, USER_TEST_ABSENT
, USER_TEST_UNDEFINED
, USER_TEST_MAYBE
))
1420 return log_error_errno(SYNTHETIC_ERRNO(EEXIST
), "Image path %s already exists, refusing.", user_record_image_path(h
));
1422 r
= home_apply_new_blob_dir(h
, blobs
);
1426 switch (user_record_storage(h
)) {
1429 r
= home_create_luks(h
, &setup
, &cache
, effective_passwords
, &new_home
);
1432 case USER_DIRECTORY
:
1433 case USER_SUBVOLUME
:
1434 r
= home_create_directory_or_subvolume(h
, &setup
, &new_home
);
1438 r
= home_create_fscrypt(h
, &setup
, effective_passwords
, &new_home
);
1442 r
= home_create_cifs(h
, &setup
, &new_home
);
1446 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
),
1447 "Creating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1452 if (user_record_equal(h
, new_home
)) {
1457 *ret_home
= TAKE_PTR(new_home
);
1461 static int home_remove(UserRecord
*h
) {
1462 bool deleted
= false;
1463 const char *ip
, *hd
;
1469 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks user name, refusing.");
1470 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
1471 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Removing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1473 hd
= user_record_home_directory(h
);
1475 r
= user_record_test_home_directory_and_warn(h
);
1478 if (r
== USER_TEST_MOUNTED
)
1479 return log_error_errno(SYNTHETIC_ERRNO(EBUSY
), "Directory %s is still mounted, refusing.", hd
);
1483 r
= user_record_test_image_path_and_warn(h
);
1487 ip
= user_record_image_path(h
);
1489 switch (user_record_storage(h
)) {
1496 if (stat(ip
, &st
) < 0) {
1497 if (errno
!= ENOENT
)
1498 return log_error_errno(errno
, "Failed to stat() %s: %m", ip
);
1501 if (S_ISREG(st
.st_mode
)) {
1502 if (unlink(ip
) < 0) {
1503 if (errno
!= ENOENT
)
1504 return log_error_errno(errno
, "Failed to remove %s: %m", ip
);
1506 _cleanup_free_
char *parent
= NULL
;
1510 r
= path_extract_directory(ip
, &parent
);
1512 log_debug_errno(r
, "Failed to determine parent directory of '%s': %m", ip
);
1514 r
= fsync_path_at(AT_FDCWD
, parent
);
1516 log_debug_errno(r
, "Failed to synchronize disk after deleting '%s', ignoring: %m", ip
);
1520 } else if (S_ISBLK(st
.st_mode
))
1521 log_info("Not removing file system on block device %s.", ip
);
1523 return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK
), "Image file %s is neither block device, nor regular, refusing removal.", ip
);
1529 case USER_SUBVOLUME
:
1530 case USER_DIRECTORY
:
1534 r
= rm_rf(ip
, REMOVE_ROOT
|REMOVE_PHYSICAL
|REMOVE_SUBVOLUME
|REMOVE_SYNCFS
);
1537 return log_warning_errno(r
, "Failed to remove %s: %m", ip
);
1541 /* If the image path and the home directory are the same invalidate the home directory, so
1542 * that we don't remove it anymore */
1543 if (path_equal(ip
, hd
))
1549 /* Nothing else to do here: we won't remove remote stuff. */
1550 log_info("Not removing home directory on remote server.");
1554 assert_not_reached();
1558 if (rmdir(hd
) < 0) {
1559 if (errno
!= ENOENT
)
1560 return log_error_errno(errno
, "Failed to remove %s, ignoring: %m", hd
);
1566 if (user_record_drop_caches(h
))
1569 log_info("Everything completed.");
1571 return log_notice_errno(SYNTHETIC_ERRNO(EALREADY
),
1572 "Nothing to remove.");
1577 static int home_basic_validate_update(UserRecord
*h
) {
1581 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks user name, refusing.");
1583 if (!uid_is_valid(h
->uid
))
1584 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks UID, refusing.");
1586 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
1587 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1592 static int home_validate_update(UserRecord
*h
, HomeSetup
*setup
, HomeSetupFlags
*flags
) {
1593 bool has_mount
= false;
1599 r
= home_basic_validate_update(h
);
1603 r
= user_record_test_home_directory_and_warn(h
);
1607 has_mount
= r
== USER_TEST_MOUNTED
;
1609 r
= user_record_test_image_path_and_warn(h
);
1612 if (r
== USER_TEST_ABSENT
)
1613 return log_error_errno(SYNTHETIC_ERRNO(ENETUNREACH
), "Image path %s does not exist", user_record_image_path(h
));
1615 switch (user_record_storage(h
)) {
1617 case USER_DIRECTORY
:
1618 case USER_SUBVOLUME
:
1624 r
= home_get_state_luks(h
, setup
);
1627 if ((r
> 0) != has_mount
)
1628 return log_error_errno(SYNTHETIC_ERRNO(EBUSY
), "Home mount incompletely set up.");
1634 assert_not_reached();
1638 SET_FLAG(*flags
, HOME_SETUP_ALREADY_ACTIVATED
, has_mount
);
1640 return has_mount
; /* return true if the home record is already active */
1643 static int home_update(UserRecord
*h
, Hashmap
*blobs
, UserRecord
**ret
) {
1644 _cleanup_(user_record_unrefp
) UserRecord
*new_home
= NULL
, *header_home
= NULL
, *embedded_home
= NULL
;
1645 _cleanup_(home_setup_done
) HomeSetup setup
= HOME_SETUP_INIT
;
1646 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1647 HomeSetupFlags flags
= 0;
1654 offline
= getenv_bool("SYSTEMD_HOMEWORK_UPDATE_OFFLINE") > 0;
1657 password_cache_load_keyring(h
, &cache
);
1659 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ true);
1662 assert(r
> 0); /* Insist that a password was verified */
1664 r
= home_validate_update(h
, &setup
, &flags
);
1666 /* In offline mode we skip all authentication, since we're
1667 * not propagating anything into the home area. The new home
1668 * records's authentication will still be checked when the user
1669 * next logs in, so this is fine */
1671 r
= home_basic_validate_update(h
);
1676 r
= home_apply_new_blob_dir(h
, blobs
);
1681 log_info("Offline update requested. Not touching embedded records.");
1682 return user_record_clone(h
, USER_RECORD_LOAD_MASK_SECRET
|USER_RECORD_PERMISSIVE
, ret
);
1685 r
= home_setup(h
, flags
, &setup
, &cache
, &header_home
);
1689 r
= home_load_embedded_identity(h
, setup
.root_fd
, header_home
, USER_RECONCILE_REQUIRE_NEWER
, &cache
, &embedded_home
, &new_home
);
1693 r
= home_maybe_shift_uid(h
, flags
, &setup
);
1697 r
= home_store_header_identity_luks(new_home
, &setup
, header_home
);
1701 r
= home_store_embedded_identity(new_home
, setup
.root_fd
, embedded_home
);
1705 r
= home_reconcile_blob_dirs(new_home
, setup
.root_fd
, USER_RECONCILE_HOST_WON
);
1709 r
= home_extend_embedded_identity(new_home
, h
, &setup
);
1713 r
= home_sync_and_statfs(setup
.root_fd
, NULL
);
1717 r
= home_setup_done(&setup
);
1721 log_info("Everything completed.");
1723 *ret
= TAKE_PTR(new_home
);
1727 static int home_resize(UserRecord
*h
, UserRecord
**ret
) {
1728 _cleanup_(home_setup_done
) HomeSetup setup
= HOME_SETUP_INIT
;
1729 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1730 HomeSetupFlags flags
= 0;
1736 if (h
->disk_size
== UINT64_MAX
)
1737 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "No target size specified, refusing.");
1739 password_cache_load_keyring(h
, &cache
);
1741 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ true);
1744 assert(r
> 0); /* Insist that a password was verified */
1746 r
= home_validate_update(h
, &setup
, &flags
);
1750 switch (user_record_storage(h
)) {
1753 return home_resize_luks(h
, flags
, &setup
, &cache
, ret
);
1755 case USER_DIRECTORY
:
1756 case USER_SUBVOLUME
:
1758 return home_resize_directory(h
, flags
, &setup
, &cache
, ret
);
1761 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Resizing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1765 static int home_passwd(UserRecord
*h
, UserRecord
**ret_home
) {
1766 _cleanup_(user_record_unrefp
) UserRecord
*header_home
= NULL
, *embedded_home
= NULL
, *new_home
= NULL
;
1767 _cleanup_strv_free_erase_
char **effective_passwords
= NULL
;
1768 _cleanup_(home_setup_done
) HomeSetup setup
= HOME_SETUP_INIT
;
1769 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1770 HomeSetupFlags flags
= 0;
1776 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
))
1777 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
)));
1779 r
= user_record_compile_effective_passwords(h
, &cache
, &effective_passwords
);
1783 r
= home_validate_update(h
, &setup
, &flags
);
1787 r
= home_setup(h
, flags
, &setup
, &cache
, &header_home
);
1791 reconciled
= home_load_embedded_identity(h
, setup
.root_fd
, header_home
, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL
, &cache
, &embedded_home
, &new_home
);
1795 r
= home_maybe_shift_uid(h
, flags
, &setup
);
1799 switch (user_record_storage(h
)) {
1802 r
= home_passwd_luks(h
, flags
, &setup
, &cache
, effective_passwords
);
1808 r
= home_passwd_fscrypt(h
, &setup
, &cache
, effective_passwords
);
1817 r
= home_store_header_identity_luks(new_home
, &setup
, header_home
);
1821 r
= home_store_embedded_identity(new_home
, setup
.root_fd
, embedded_home
);
1825 r
= home_reconcile_blob_dirs(new_home
, setup
.root_fd
, reconciled
);
1829 r
= home_extend_embedded_identity(new_home
, h
, &setup
);
1833 r
= home_sync_and_statfs(setup
.root_fd
, NULL
);
1837 r
= home_setup_done(&setup
);
1841 log_info("Everything completed.");
1843 *ret_home
= TAKE_PTR(new_home
);
1847 static int home_inspect(UserRecord
*h
, UserRecord
**ret_home
) {
1848 _cleanup_(user_record_unrefp
) UserRecord
*header_home
= NULL
, *new_home
= NULL
;
1849 _cleanup_(home_setup_done
) HomeSetup setup
= HOME_SETUP_INIT
;
1850 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1851 HomeSetupFlags flags
= 0;
1857 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ false);
1861 r
= home_validate_update(h
, &setup
, &flags
);
1865 r
= home_setup(h
, flags
, &setup
, &cache
, &header_home
);
1869 r
= home_load_embedded_identity(h
, setup
.root_fd
, header_home
, USER_RECONCILE_ANY
, &cache
, NULL
, &new_home
);
1873 r
= home_extend_embedded_identity(new_home
, h
, &setup
);
1877 r
= home_setup_done(&setup
);
1881 log_info("Everything completed.");
1883 *ret_home
= TAKE_PTR(new_home
);
1887 static int user_session_freezer_new(uid_t uid
, UnitFreezer
**ret
) {
1888 _cleanup_free_
char *unit
= NULL
;
1891 assert(uid_is_valid(uid
));
1894 r
= getenv_bool("SYSTEMD_HOME_LOCK_FREEZE_SESSION");
1895 if (r
< 0 && r
!= -ENXIO
)
1896 log_warning_errno(r
, "Cannot parse value of $SYSTEMD_HOME_LOCK_FREEZE_SESSION, ignoring: %m");
1902 if (asprintf(&unit
, "user-" UID_FMT
".slice", uid
) < 0)
1905 r
= unit_freezer_new(unit
, ret
);
1912 static int home_lock(UserRecord
*h
) {
1913 _cleanup_(home_setup_done
) HomeSetup setup
= HOME_SETUP_INIT
;
1919 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record incomplete, refusing.");
1920 if (user_record_storage(h
) != USER_LUKS
)
1921 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Locking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1923 r
= user_record_test_home_directory_and_warn(h
);
1926 if (r
!= USER_TEST_MOUNTED
)
1927 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC
), "Home directory of %s is not mounted, can't lock.", h
->user_name
);
1929 _cleanup_(unit_freezer_freep
) UnitFreezer
*f
= NULL
;
1931 r
= user_session_freezer_new(h
->uid
, &f
);
1935 r
= unit_freezer_freeze(f
);
1939 log_notice("Session remains unfrozen on explicit request ($SYSTEMD_HOME_LOCK_FREEZE_SESSION=0).\n"
1940 "This is not recommended, and might result in unexpected behavior including data loss!");
1942 r
= home_lock_luks(h
, &setup
);
1945 (void) unit_freezer_thaw(f
);
1950 /* Explicitly flush any per-user key from the keyring */
1951 (void) keyring_flush(h
);
1953 log_info("Everything completed.");
1957 static int home_unlock(UserRecord
*h
) {
1958 _cleanup_(home_setup_done
) HomeSetup setup
= HOME_SETUP_INIT
;
1959 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1965 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record incomplete, refusing.");
1966 if (user_record_storage(h
) != USER_LUKS
)
1967 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Unlocking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1969 /* Note that we don't check if $HOME is actually mounted, since we want to avoid disk accesses on
1970 * that mount until we have resumed the device. */
1972 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ false);
1976 r
= home_unlock_luks(h
, &setup
, &cache
);
1980 _cleanup_(unit_freezer_freep
) UnitFreezer
*f
= NULL
;
1982 /* We want to thaw the session only after it's safe to access $HOME */
1983 r
= user_session_freezer_new(h
->uid
, &f
);
1985 r
= unit_freezer_thaw(f
);
1989 log_info("Everything completed.");
1993 static int run(int argc
, char *argv
[]) {
1994 _cleanup_(user_record_unrefp
) UserRecord
*home
= NULL
, *new_home
= NULL
;
1995 _cleanup_(sd_json_variant_unrefp
) sd_json_variant
*v
= NULL
;
1996 _cleanup_fclose_
FILE *opened_file
= NULL
;
1997 _cleanup_hashmap_free_ Hashmap
*blobs
= NULL
;
1998 const char *json_path
= NULL
, *blob_filename
;
2001 sd_json_variant
*fdmap
, *blob_fd_variant
;
2004 start
= now(CLOCK_MONOTONIC
);
2008 cryptsetup_enable_logging(NULL
);
2012 if (argc
< 2 || argc
> 3)
2013 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "This program takes one or two arguments.");
2016 json_path
= argv
[2];
2018 opened_file
= fopen(json_path
, "re");
2020 return log_error_errno(errno
, "Failed to open %s: %m", json_path
);
2022 json_file
= opened_file
;
2024 json_path
= "<stdin>";
2028 unsigned line
= 0, column
= 0;
2029 r
= sd_json_parse_file(json_file
, json_path
, SD_JSON_PARSE_SENSITIVE
, &v
, &line
, &column
);
2031 return log_error_errno(r
, "[%s:%u:%u] Failed to parse JSON data: %m", json_path
, line
, column
);
2033 fdmap
= sd_json_variant_by_key(v
, HOMEWORK_BLOB_FDMAP_FIELD
);
2035 r
= hashmap_ensure_allocated(&blobs
, &blob_fd_hash_ops
);
2039 JSON_VARIANT_OBJECT_FOREACH(blob_filename
, blob_fd_variant
, fdmap
) {
2040 _cleanup_free_
char *filename
= NULL
;
2041 _cleanup_close_
int fd
= -EBADF
;
2043 assert(sd_json_variant_is_integer(blob_fd_variant
));
2044 assert(sd_json_variant_integer(blob_fd_variant
) >= 0);
2045 assert(sd_json_variant_integer(blob_fd_variant
) <= INT_MAX
- SD_LISTEN_FDS_START
);
2046 fd
= SD_LISTEN_FDS_START
+ (int) sd_json_variant_integer(blob_fd_variant
);
2048 if (DEBUG_LOGGING
) {
2049 _cleanup_free_
char *resolved
= NULL
;
2050 r
= fd_get_path(fd
, &resolved
);
2051 log_debug("Got blob from daemon: %s (%d) → %s",
2052 blob_filename
, fd
, resolved
?: STRERROR(r
));
2055 filename
= strdup(blob_filename
);
2059 r
= fd_cloexec(fd
, true);
2061 return log_error_errno(r
, "Failed to enable O_CLOEXEC on blob %s: %m", filename
);
2063 r
= hashmap_put(blobs
, filename
, FD_TO_PTR(fd
));
2065 return log_error_errno(r
, "Failed to insert blob %s into map: %m", filename
);
2066 TAKE_PTR(filename
); /* Ownership transfers to hashmap */
2070 r
= sd_json_variant_filter(&v
, STRV_MAKE(HOMEWORK_BLOB_FDMAP_FIELD
));
2072 return log_error_errno(r
, "Failed to strip internal fdmap from JSON: %m");
2075 home
= user_record_new();
2079 r
= user_record_load(home
, v
, USER_RECORD_LOAD_FULL
|USER_RECORD_LOG
|USER_RECORD_PERMISSIVE
);
2083 /* Well known return values of these operations, that systemd-homed knows and converts to proper D-Bus errors:
2085 * EMSGSIZE → file systems of this type cannot be shrunk
2086 * ETXTBSY → file systems of this type can only be shrunk offline
2087 * ERANGE → file system size too small
2088 * ENOLINK → system does not support selected storage backend
2089 * EPROTONOSUPPORT → system does not support selected file system
2090 * ENOTTY → operation not support on this storage
2091 * ESOCKTNOSUPPORT → operation not support on this file system
2092 * ENOKEY → password incorrect (or not sufficient, or not supplied)
2093 * EREMOTEIO → recovery key incorrect (or not sufficeint, or not supplied — only if no passwords defined)
2094 * EBADSLT → similar, but PKCS#11 device is defined and might be able to provide password, if it was plugged in which it is not
2095 * ENOANO → suitable PKCS#11/FIDO2 device found, but PIN is missing to unlock it
2096 * ERFKILL → suitable PKCS#11 device found, but OK to ask for on-device interactive authentication not given
2097 * EMEDIUMTYPE → suitable FIDO2 device found, but OK to ask for user presence not given
2098 * ENOCSI → suitable FIDO2 device found, but OK to ask for user verification not given
2099 * ENOSTR → suitable FIDO2 device found, but user didn't react to action request on token quickly enough
2100 * EOWNERDEAD → suitable PKCS#11/FIDO2 device found, but its PIN is locked
2101 * ENOLCK → suitable PKCS#11/FIDO2 device found, but PIN incorrect
2102 * ETOOMANYREFS → suitable PKCS#11 device found, but PIN incorrect, and only few tries left
2103 * EUCLEAN → suitable PKCS#11 device found, but PIN incorrect, and only one try left
2104 * EBUSY → file system is currently active
2105 * ENOEXEC → file system is currently not active
2106 * ENOSPC → not enough disk space for operation
2107 * EKEYREVOKED → user record has not suitable hashed password or pkcs#11 entry, we cannot authenticate
2108 * EADDRINUSE → home image is already used elsewhere (lock taken)
2109 * ENETUNREACH → backing storage is currently not (image is ENOENT, or AF_UNIX socket to connect to is ENOENT)
2112 if (streq(argv
[1], "activate"))
2113 r
= home_activate(home
, &new_home
);
2114 else if (streq(argv
[1], "deactivate"))
2115 r
= home_deactivate(home
, false);
2116 else if (streq(argv
[1], "deactivate-force"))
2117 r
= home_deactivate(home
, true);
2118 else if (streq(argv
[1], "create"))
2119 r
= home_create(home
, blobs
, &new_home
);
2120 else if (streq(argv
[1], "remove"))
2121 r
= home_remove(home
);
2122 else if (streq(argv
[1], "update"))
2123 r
= home_update(home
, blobs
, &new_home
);
2124 else if (streq(argv
[1], "resize"))
2125 r
= home_resize(home
, &new_home
);
2126 else if (streq(argv
[1], "passwd"))
2127 r
= home_passwd(home
, &new_home
);
2128 else if (streq(argv
[1], "inspect"))
2129 r
= home_inspect(home
, &new_home
);
2130 else if (streq(argv
[1], "lock"))
2131 r
= home_lock(home
);
2132 else if (streq(argv
[1], "unlock"))
2133 r
= home_unlock(home
);
2135 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Unknown verb '%s'.", argv
[1]);
2136 if (IN_SET(r
, -ENOKEY
, -EREMOTEIO
) && !strv_isempty(home
->password
) ) { /* There were passwords specified but they were incorrect */
2139 /* Make sure bad password replies always take at least 3s, and if longer multiples of 3s, so
2140 * that it's not clear how long we actually needed for our calculations. */
2141 n
= now(CLOCK_MONOTONIC
);
2144 d
= usec_sub_unsigned(n
, start
);
2145 if (d
> BAD_PASSWORD_DELAY_USEC
)
2146 end
= start
+ DIV_ROUND_UP(d
, BAD_PASSWORD_DELAY_USEC
) * BAD_PASSWORD_DELAY_USEC
;
2148 end
= start
+ BAD_PASSWORD_DELAY_USEC
;
2151 (void) usleep_safe(usec_sub_unsigned(end
, n
));
2156 /* We always pass the new record back, regardless if it changed or not. This allows our caller to
2157 * prepare a fresh record, send to us, and only if it works use it without having to keep a local
2160 sd_json_variant_dump(new_home
->json
, SD_JSON_FORMAT_NEWLINE
, stdout
, NULL
);
2165 DEFINE_MAIN_FUNCTION(run
);