1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
6 #include "chown-recursive.h"
11 #include "home-util.h"
12 #include "homework-cifs.h"
13 #include "homework-directory.h"
14 #include "homework-fido2.h"
15 #include "homework-fscrypt.h"
16 #include "homework-luks.h"
17 #include "homework-mount.h"
18 #include "homework-pkcs11.h"
20 #include "libcrypt-util.h"
21 #include "main-func.h"
22 #include "memory-util.h"
23 #include "missing_magic.h"
25 #include "mount-util.h"
26 #include "path-util.h"
28 #include "stat-util.h"
30 #include "tmpfile-util.h"
31 #include "user-util.h"
34 /* Make sure a bad password always results in a 3s delay, no matter what */
35 #define BAD_PASSWORD_DELAY_USEC (3 * USEC_PER_SEC)
37 void password_cache_free(PasswordCache
*cache
) {
41 cache
->pkcs11_passwords
= strv_free_erase(cache
->pkcs11_passwords
);
42 cache
->fido2_passwords
= strv_free_erase(cache
->fido2_passwords
);
45 int user_record_authenticate(
51 bool need_password
= false, need_recovery_key
= false, need_token
= false, need_pin
= false, need_protected_authentication_path_permitted
= false, need_user_presence_permitted
= false,
52 pin_locked
= false, pin_incorrect
= false, pin_incorrect_few_tries_left
= false, pin_incorrect_one_try_left
= false, token_action_timeout
= false;
58 /* Tries to authenticate a user record with the supplied secrets. i.e. checks whether at least one
59 * supplied plaintext passwords matches a hashed password field of the user record. Or if a
60 * configured PKCS#11 or FIDO2 token is around and can unlock the record.
62 * Note that the 'cache' parameter is both an input and output parameter: it contains lists of
63 * configured, decrypted PKCS#11/FIDO2 passwords. We typically have to call this function multiple
64 * times over the course of an operation (think: on login we authenticate the host user record, the
65 * record embedded in the LUKS record and the one embedded in $HOME). Hence we keep a list of
66 * passwords we already decrypted, so that we don't have to do the (slow and potentially interactive)
67 * PKCS#11/FIDO2 dance for the relevant token again and again. */
69 /* First, let's see if the supplied plain-text passwords work? */
70 r
= user_record_test_password(h
, secret
);
74 log_debug_errno(r
, "User record has no hashed passwords, plaintext passwords not tested.");
76 return log_error_errno(r
, "Failed to validate password of record: %m");
78 log_info("Provided password unlocks user record.");
82 /* Similar, but test against the recovery keys */
83 r
= user_record_test_recovery_key(h
, secret
);
85 need_recovery_key
= true;
87 log_debug_errno(r
, "User record has no recovery keys, plaintext passwords not tested against it.");
89 return log_error_errno(r
, "Failed to validate the recovery key of the record: %m");
91 log_info("Provided password is a recovery key that unlocks the user record.");
95 if (need_password
&& need_recovery_key
)
96 log_info("None of the supplied plaintext passwords unlock the user record's hashed passwords or recovery keys.");
97 else if (need_password
)
98 log_info("None of the supplied plaintext passwords unlock the user record's hashed passwords.");
100 log_info("None of the supplied plaintext passwords unlock the user record's hashed recovery keys.");
102 /* Second, test cached PKCS#11 passwords */
103 for (size_t n
= 0; n
< h
->n_pkcs11_encrypted_key
; n
++) {
106 STRV_FOREACH(pp
, cache
->pkcs11_passwords
) {
107 r
= test_password_one(h
->pkcs11_encrypted_key
[n
].hashed_password
, *pp
);
109 return log_error_errno(r
, "Failed to check supplied PKCS#11 password: %m");
111 log_info("Previously acquired PKCS#11 password unlocks user record.");
117 /* Third, test cached FIDO2 passwords */
118 for (size_t n
= 0; n
< h
->n_fido2_hmac_salt
; n
++) {
121 /* See if any of the previously calculated passwords work */
122 STRV_FOREACH(pp
, cache
->fido2_passwords
) {
123 r
= test_password_one(h
->fido2_hmac_salt
[n
].hashed_password
, *pp
);
125 return log_error_errno(r
, "Failed to check supplied FIDO2 password: %m");
127 log_info("Previously acquired FIDO2 password unlocks user record.");
133 /* Fourth, let's see if any of the PKCS#11 security tokens are plugged in and help us */
134 for (size_t n
= 0; n
< h
->n_pkcs11_encrypted_key
; n
++) {
136 _cleanup_(pkcs11_callback_data_release
) struct pkcs11_callback_data data
= {
139 .encrypted_key
= h
->pkcs11_encrypted_key
+ n
,
142 r
= pkcs11_find_token(data
.encrypted_key
->uri
, pkcs11_callback
, &data
);
151 need_protected_authentication_path_permitted
= true;
157 pin_incorrect
= true;
160 pin_incorrect
= pin_incorrect_few_tries_left
= true;
163 pin_incorrect
= pin_incorrect_few_tries_left
= pin_incorrect_one_try_left
= true;
169 r
= test_password_one(data
.encrypted_key
->hashed_password
, data
.decrypted_password
);
171 return log_error_errno(r
, "Failed to test PKCS#11 password: %m");
173 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Configured PKCS#11 security token %s does not decrypt encrypted key correctly.", data
.encrypted_key
->uri
);
175 log_info("Decrypted password from PKCS#11 security token %s unlocks user record.", data
.encrypted_key
->uri
);
177 r
= strv_extend(&cache
->pkcs11_passwords
, data
.decrypted_password
);
189 /* Fifth, let's see if any of the FIDO2 security tokens are plugged in and help us */
190 for (size_t n
= 0; n
< h
->n_fido2_hmac_salt
; n
++) {
192 _cleanup_(erase_and_freep
) char *decrypted_password
= NULL
;
194 r
= fido2_use_token(h
, secret
, h
->fido2_hmac_salt
+ n
, &decrypted_password
);
206 pin_incorrect
= true;
209 need_user_presence_permitted
= true;
212 token_action_timeout
= true;
218 r
= test_password_one(h
->fido2_hmac_salt
[n
].hashed_password
, decrypted_password
);
220 return log_error_errno(r
, "Failed to test FIDO2 password: %m");
222 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Configured FIDO2 security token does not decrypt encrypted key correctly.");
224 log_info("Decrypted password from FIDO2 security token unlocks user record.");
226 r
= strv_extend(&cache
->fido2_passwords
, decrypted_password
);
238 /* Ordered by "relevance", i.e. the most "important" or "interesting" error condition is returned. */
239 if (pin_incorrect_one_try_left
)
241 if (pin_incorrect_few_tries_left
)
242 return -ETOOMANYREFS
;
247 if (token_action_timeout
)
249 if (need_protected_authentication_path_permitted
)
251 if (need_user_presence_permitted
)
259 if (need_recovery_key
)
262 /* Hmm, this means neither PCKS#11/FIDO2 nor classic hashed passwords or recovery keys were supplied,
263 * we cannot authenticate this reasonably */
265 return log_debug_errno(SYNTHETIC_ERRNO(EKEYREVOKED
),
266 "No hashed passwords, no recovery keys and no PKCS#11/FIDO2 tokens defined, cannot authenticate user record, refusing.");
268 /* If strict verification is off this means we are possibly in the case where we encountered an
269 * unfixated record, i.e. a synthetic one that accordingly lacks any authentication data. In this
270 * case, allow the authentication to pass for now, so that the second (or third) authentication level
271 * (the ones of the user record in the LUKS header or inside the home directory) will then catch
272 * invalid passwords. The second/third authentication always runs in strict verification mode. */
273 log_debug("No hashed passwords, not recovery keys and no PKCS#11 tokens defined in record, cannot authenticate user record. "
274 "Deferring to embedded user record.");
278 int home_setup_undo(HomeSetup
*setup
) {
283 if (setup
->root_fd
>= 0) {
284 if (setup
->do_offline_fitrim
) {
285 q
= run_fitrim(setup
->root_fd
);
290 setup
->root_fd
= safe_close(setup
->root_fd
);
293 if (setup
->undo_mount
) {
294 q
= umount_verbose(LOG_DEBUG
, "/run/systemd/user-home-mount", UMOUNT_NOFOLLOW
);
299 if (setup
->undo_dm
&& setup
->crypt_device
&& setup
->dm_name
) {
300 q
= crypt_deactivate(setup
->crypt_device
, setup
->dm_name
);
305 if (setup
->image_fd
>= 0) {
306 if (setup
->do_offline_fallocate
) {
307 q
= run_fallocate(setup
->image_fd
, NULL
);
312 if (setup
->do_mark_clean
) {
313 q
= run_mark_dirty(setup
->image_fd
, false);
318 setup
->image_fd
= safe_close(setup
->image_fd
);
321 setup
->undo_mount
= false;
322 setup
->undo_dm
= false;
323 setup
->do_offline_fitrim
= false;
324 setup
->do_offline_fallocate
= false;
325 setup
->do_mark_clean
= false;
327 setup
->dm_name
= mfree(setup
->dm_name
);
328 setup
->dm_node
= mfree(setup
->dm_node
);
330 setup
->loop
= loop_device_unref(setup
->loop
);
331 crypt_free(setup
->crypt_device
);
332 setup
->crypt_device
= NULL
;
334 explicit_bzero_safe(setup
->volume_key
, setup
->volume_key_size
);
335 setup
->volume_key
= mfree(setup
->volume_key
);
336 setup
->volume_key_size
= 0;
343 bool already_activated
,
344 PasswordCache
*cache
,
346 UserRecord
**ret_header_home
) {
352 assert(!setup
->loop
);
353 assert(!setup
->crypt_device
);
354 assert(setup
->root_fd
< 0);
355 assert(!setup
->undo_dm
);
356 assert(!setup
->undo_mount
);
358 /* Makes a home directory accessible (through the root_fd file descriptor, not by path!). */
360 switch (user_record_storage(h
)) {
363 return home_prepare_luks(h
, already_activated
, NULL
, cache
, setup
, ret_header_home
);
367 r
= home_prepare_directory(h
, already_activated
, setup
);
371 r
= home_prepare_fscrypt(h
, already_activated
, cache
, setup
);
375 r
= home_prepare_cifs(h
, already_activated
, setup
);
379 return log_error_errno(SYNTHETIC_ERRNO(ENOLINK
), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
386 *ret_header_home
= NULL
;
391 int home_sync_and_statfs(int root_fd
, struct statfs
*ret
) {
392 assert(root_fd
>= 0);
394 /* Let's sync this to disk, so that the disk space reported by fstatfs() below is accurate (for file
395 * systems such as btrfs where this is determined lazily). */
397 if (syncfs(root_fd
) < 0)
398 return log_error_errno(errno
, "Failed to synchronize file system: %m");
401 if (fstatfs(root_fd
, ret
) < 0)
402 return log_error_errno(errno
, "Failed to statfs() file system: %m");
404 log_info("Synchronized disk.");
409 static int read_identity_file(int root_fd
, JsonVariant
**ret
) {
410 _cleanup_(fclosep
) FILE *identity_file
= NULL
;
411 _cleanup_close_
int identity_fd
= -1;
412 unsigned line
, column
;
415 assert(root_fd
>= 0);
418 identity_fd
= openat(root_fd
, ".identity", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
|O_NONBLOCK
);
420 return log_error_errno(errno
, "Failed to open .identity file in home directory: %m");
422 r
= fd_verify_regular(identity_fd
);
424 return log_error_errno(r
, "Embedded identity file is not a regular file, refusing: %m");
426 identity_file
= take_fdopen(&identity_fd
, "r");
430 r
= json_parse_file(identity_file
, ".identity", JSON_PARSE_SENSITIVE
, ret
, &line
, &column
);
432 return log_error_errno(r
, "[.identity:%u:%u] Failed to parse JSON data: %m", line
, column
);
434 log_info("Read embedded .identity file.");
439 static int write_identity_file(int root_fd
, JsonVariant
*v
, uid_t uid
) {
440 _cleanup_(json_variant_unrefp
) JsonVariant
*normalized
= NULL
;
441 _cleanup_(fclosep
) FILE *identity_file
= NULL
;
442 _cleanup_close_
int identity_fd
= -1;
443 _cleanup_free_
char *fn
= NULL
;
446 assert(root_fd
>= 0);
449 normalized
= json_variant_ref(v
);
451 r
= json_variant_normalize(&normalized
);
453 log_warning_errno(r
, "Failed to normalize user record, ignoring: %m");
455 r
= tempfn_random(".identity", NULL
, &fn
);
459 identity_fd
= openat(root_fd
, fn
, O_WRONLY
|O_CREAT
|O_EXCL
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
, 0600);
461 return log_error_errno(errno
, "Failed to create .identity file in home directory: %m");
463 identity_file
= take_fdopen(&identity_fd
, "w");
464 if (!identity_file
) {
469 json_variant_dump(normalized
, JSON_FORMAT_PRETTY
, identity_file
, NULL
);
471 r
= fflush_and_check(identity_file
);
473 log_error_errno(r
, "Failed to write .identity file: %m");
477 if (fchown(fileno(identity_file
), uid
, uid
) < 0) {
478 log_error_errno(r
, "Failed to change ownership of identity file: %m");
482 if (renameat(root_fd
, fn
, root_fd
, ".identity") < 0) {
483 r
= log_error_errno(errno
, "Failed to move identity file into place: %m");
487 log_info("Wrote embedded .identity file.");
492 (void) unlinkat(root_fd
, fn
, 0);
496 int home_load_embedded_identity(
499 UserRecord
*header_home
,
500 UserReconcileMode mode
,
501 PasswordCache
*cache
,
502 UserRecord
**ret_embedded_home
,
503 UserRecord
**ret_new_home
) {
505 _cleanup_(user_record_unrefp
) UserRecord
*embedded_home
= NULL
, *intermediate_home
= NULL
, *new_home
= NULL
;
506 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
510 assert(root_fd
>= 0);
512 r
= read_identity_file(root_fd
, &v
);
516 embedded_home
= user_record_new();
520 r
= user_record_load(embedded_home
, v
, USER_RECORD_LOAD_EMBEDDED
);
524 if (!user_record_compatible(h
, embedded_home
))
525 return log_error_errno(SYNTHETIC_ERRNO(EREMCHG
), "Embedded home record not compatible with host record, refusing.");
527 /* Insist that credentials the user supplies also unlocks any embedded records. */
528 r
= user_record_authenticate(embedded_home
, h
, cache
, /* strict_verify= */ true);
531 assert(r
> 0); /* Insist that a password was verified */
533 /* At this point we have three records to deal with:
535 * · The record we got passed from the host
536 * · The record included in the LUKS header (only if LUKS is used)
537 * · The record in the home directory itself (~.identity)
539 * Now we have to reconcile all three, and let the newest one win. */
542 /* Note we relax the requirements here. Instead of insisting that the host record is strictly
543 * newer, let's also be OK if its equally new. If it is, we'll however insist that the
544 * embedded record must be newer, so that we update at least one of the two. */
546 r
= user_record_reconcile(h
, header_home
, mode
== USER_RECONCILE_REQUIRE_NEWER
? USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL
: mode
, &intermediate_home
);
547 if (r
== -EREMCHG
) /* this was supposed to be checked earlier already, but let's check this again */
548 return log_error_errno(r
, "Identity stored on host and in header don't match, refusing.");
550 return log_error_errno(r
, "Embedded identity record is newer than supplied record, refusing.");
552 return log_error_errno(r
, "Failed to reconcile host and header identities: %m");
553 if (r
== USER_RECONCILE_EMBEDDED_WON
)
554 log_info("Reconciling header user identity completed (header version was newer).");
555 else if (r
== USER_RECONCILE_HOST_WON
) {
556 log_info("Reconciling header user identity completed (host version was newer).");
558 if (mode
== USER_RECONCILE_REQUIRE_NEWER
) /* Host version is newer than the header
559 * version, hence we'll update
560 * something. This means we can relax the
561 * requirements on the embedded
563 mode
= USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL
;
565 assert(r
== USER_RECONCILE_IDENTICAL
);
566 log_info("Reconciling user identities completed (host and header version were identical).");
569 h
= intermediate_home
;
572 r
= user_record_reconcile(h
, embedded_home
, mode
, &new_home
);
574 return log_error_errno(r
, "Identity stored on host and in home don't match, refusing.");
576 return log_error_errno(r
, "Embedded identity record is equally new or newer than supplied record, refusing.");
578 return log_error_errno(r
, "Failed to reconcile host and embedded identities: %m");
579 if (r
== USER_RECONCILE_EMBEDDED_WON
)
580 log_info("Reconciling embedded user identity completed (embedded version was newer).");
581 else if (r
== USER_RECONCILE_HOST_WON
)
582 log_info("Reconciling embedded user identity completed (host version was newer).");
584 assert(r
== USER_RECONCILE_IDENTICAL
);
585 log_info("Reconciling embedded user identity completed (host and embedded version were identical).");
588 if (ret_embedded_home
)
589 *ret_embedded_home
= TAKE_PTR(embedded_home
);
592 *ret_new_home
= TAKE_PTR(new_home
);
597 int home_store_embedded_identity(UserRecord
*h
, int root_fd
, uid_t uid
, UserRecord
*old_home
) {
598 _cleanup_(user_record_unrefp
) UserRecord
*embedded
= NULL
;
602 assert(root_fd
>= 0);
603 assert(uid_is_valid(uid
));
605 r
= user_record_clone(h
, USER_RECORD_EXTRACT_EMBEDDED
, &embedded
);
607 return log_error_errno(r
, "Failed to determine new embedded record: %m");
609 if (old_home
&& user_record_equal(old_home
, embedded
)) {
610 log_debug("Not updating embedded home record.");
614 /* The identity has changed, let's update it in the image */
615 r
= write_identity_file(root_fd
, embedded
->json
, h
->uid
);
622 static const char *file_system_type_fd(int fd
) {
627 if (fstatfs(fd
, &sfs
) < 0) {
628 log_debug_errno(errno
, "Failed to statfs(): %m");
632 if (is_fs_type(&sfs
, XFS_SB_MAGIC
))
634 if (is_fs_type(&sfs
, EXT4_SUPER_MAGIC
))
636 if (is_fs_type(&sfs
, BTRFS_SUPER_MAGIC
))
642 int home_extend_embedded_identity(UserRecord
*h
, UserRecord
*used
, HomeSetup
*setup
) {
649 r
= user_record_add_binding(
651 user_record_storage(used
),
652 user_record_image_path(used
),
653 setup
->found_partition_uuid
,
654 setup
->found_luks_uuid
,
655 setup
->found_fs_uuid
,
656 setup
->crypt_device
? crypt_get_cipher(setup
->crypt_device
) : NULL
,
657 setup
->crypt_device
? crypt_get_cipher_mode(setup
->crypt_device
) : NULL
,
658 setup
->crypt_device
? luks_volume_key_size_convert(setup
->crypt_device
) : UINT64_MAX
,
659 file_system_type_fd(setup
->root_fd
),
660 user_record_home_directory(used
),
664 return log_error_errno(r
, "Failed to update binding in record: %m");
669 static int chown_recursive_directory(int root_fd
, uid_t uid
) {
672 assert(root_fd
>= 0);
673 assert(uid_is_valid(uid
));
675 r
= fd_chown_recursive(root_fd
, uid
, (gid_t
) uid
, 0777);
677 return log_error_errno(r
, "Failed to change ownership of files and directories: %m");
679 log_info("Recursive changing of ownership not necessary, skipped.");
681 log_info("Recursive changing of ownership completed.");
689 UserRecord
*header_home
,
690 PasswordCache
*cache
,
691 struct statfs
*ret_statfs
,
692 UserRecord
**ret_new_home
) {
694 _cleanup_(user_record_unrefp
) UserRecord
*embedded_home
= NULL
, *new_home
= NULL
;
699 assert(ret_new_home
);
701 /* When activating a home directory, does the identity work: loads the identity from the $HOME
702 * directory, reconciles it with our idea, chown()s everything. */
704 r
= home_load_embedded_identity(h
, setup
->root_fd
, header_home
, USER_RECONCILE_ANY
, cache
, &embedded_home
, &new_home
);
708 r
= home_store_header_identity_luks(new_home
, setup
, header_home
);
712 r
= home_store_embedded_identity(new_home
, setup
->root_fd
, h
->uid
, embedded_home
);
716 r
= chown_recursive_directory(setup
->root_fd
, h
->uid
);
720 r
= home_sync_and_statfs(setup
->root_fd
, ret_statfs
);
724 *ret_new_home
= TAKE_PTR(new_home
);
728 static int home_activate(UserRecord
*h
, UserRecord
**ret_home
) {
729 _cleanup_(password_cache_free
) PasswordCache cache
= {};
730 _cleanup_(user_record_unrefp
) UserRecord
*new_home
= NULL
;
736 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks user name, refusing.");
737 if (!uid_is_valid(h
->uid
))
738 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks UID, refusing.");
739 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
740 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Activating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
742 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ false);
746 r
= user_record_test_home_directory_and_warn(h
);
749 if (r
== USER_TEST_MOUNTED
)
750 return log_error_errno(SYNTHETIC_ERRNO(EALREADY
), "Home directory %s is already mounted, refusing.", user_record_home_directory(h
));
752 r
= user_record_test_image_path_and_warn(h
);
755 if (r
== USER_TEST_ABSENT
)
756 return log_error_errno(SYNTHETIC_ERRNO(ENOENT
), "Image path %s is missing, refusing.", user_record_image_path(h
));
758 switch (user_record_storage(h
)) {
761 r
= home_activate_luks(h
, &cache
, &new_home
);
770 r
= home_activate_directory(h
, &cache
, &new_home
);
777 r
= home_activate_cifs(h
, &cache
, &new_home
);
784 assert_not_reached("unexpected type");
787 /* Note that the returned object might either be a reference to an updated version of the existing
788 * home object, or a reference to a newly allocated home object. The caller has to be able to deal
789 * with both, and consider the old object out-of-date. */
790 if (user_record_equal(h
, new_home
)) {
792 return 0; /* no identity change */
795 *ret_home
= TAKE_PTR(new_home
);
796 return 1; /* identity updated */
799 static int home_deactivate(UserRecord
*h
, bool force
) {
806 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record incomplete, refusing.");
807 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
808 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Deactivating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
810 r
= user_record_test_home_directory_and_warn(h
);
813 if (r
== USER_TEST_MOUNTED
) {
814 if (user_record_storage(h
) == USER_LUKS
) {
815 r
= home_trim_luks(h
);
820 if (umount2(user_record_home_directory(h
), UMOUNT_NOFOLLOW
| (force
? MNT_FORCE
|MNT_DETACH
: 0)) < 0)
821 return log_error_errno(errno
, "Failed to unmount %s: %m", user_record_home_directory(h
));
823 log_info("Unmounting completed.");
826 log_info("Directory %s is already unmounted.", user_record_home_directory(h
));
828 if (user_record_storage(h
) == USER_LUKS
) {
829 r
= home_deactivate_luks(h
);
837 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC
), "Home is not active.");
839 log_info("Everything completed.");
843 static int copy_skel(int root_fd
, const char *skel
) {
846 assert(root_fd
>= 0);
848 r
= copy_tree_at(AT_FDCWD
, skel
, root_fd
, ".", UID_INVALID
, GID_INVALID
, COPY_MERGE
|COPY_REPLACE
);
850 log_info("Skeleton directory %s missing, ignoring.", skel
);
854 return log_error_errno(r
, "Failed to copy in %s: %m", skel
);
856 log_info("Copying in %s completed.", skel
);
860 static int change_access_mode(int root_fd
, mode_t m
) {
861 assert(root_fd
>= 0);
863 if (fchmod(root_fd
, m
) < 0)
864 return log_error_errno(errno
, "Failed to change access mode of top-level directory: %m");
866 log_info("Changed top-level directory access mode to 0%o.", m
);
870 int home_populate(UserRecord
*h
, int dir_fd
) {
876 r
= copy_skel(dir_fd
, user_record_skeleton_directory(h
));
880 r
= home_store_embedded_identity(h
, dir_fd
, h
->uid
, NULL
);
884 r
= chown_recursive_directory(dir_fd
, h
->uid
);
888 r
= change_access_mode(dir_fd
, user_record_access_mode(h
));
895 static int user_record_compile_effective_passwords(
897 PasswordCache
*cache
,
898 char ***ret_effective_passwords
) {
900 _cleanup_(strv_free_erasep
) char **effective
= NULL
;
908 /* We insist on at least one classic hashed password to be defined in addition to any PKCS#11 one, as
909 * a safe fallback, but also to simplify the password changing algorithm: there we require providing
910 * the old literal password only (and do not care for the old PKCS#11 token) */
912 if (strv_isempty(h
->hashed_password
))
913 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
),
914 "User record has no hashed passwords, refusing.");
916 /* Generates the list of plaintext passwords to propagate to LUKS/fscrypt devices, and checks whether
917 * we have a plaintext password for each hashed one. If we are missing one we'll fail, since we
918 * couldn't sync fscrypt/LUKS to the login account properly. */
920 STRV_FOREACH(i
, h
->hashed_password
) {
924 log_debug("Looking for plaintext password for: %s", *i
);
926 /* Let's scan all provided plaintext passwords */
927 STRV_FOREACH(j
, h
->password
) {
928 r
= test_password_one(*i
, *j
);
930 return log_error_errno(r
, "Failed to test plaintext password: %m");
932 if (ret_effective_passwords
) {
933 r
= strv_extend(&effective
, *j
);
938 log_debug("Found literal plaintext password.");
945 return log_error_errno(SYNTHETIC_ERRNO(ENOKEY
), "Missing plaintext password for defined hashed password");
948 for (n
= 0; n
< h
->n_recovery_key
; n
++) {
952 log_debug("Looking for plaintext recovery key for: %s", h
->recovery_key
[n
].hashed_password
);
954 STRV_FOREACH(j
, h
->password
) {
955 _cleanup_(erase_and_freep
) char *mangled
= NULL
;
958 if (streq(h
->recovery_key
[n
].type
, "modhex64")) {
960 r
= normalize_recovery_key(*j
, &mangled
);
961 if (r
== -EINVAL
) /* Not properly formatted, probably a regular password. */
964 return log_error_errno(r
, "Failed to normalize recovery key: %m");
970 r
= test_password_one(h
->recovery_key
[n
].hashed_password
, p
);
972 return log_error_errno(r
, "Failed to test plaintext recovery key: %m");
974 if (ret_effective_passwords
) {
975 r
= strv_extend(&effective
, p
);
980 log_debug("Found plaintext recovery key.");
987 return log_error_errno(SYNTHETIC_ERRNO(EREMOTEIO
), "Missing plaintext recovery key for defined recovery key");
990 for (n
= 0; n
< h
->n_pkcs11_encrypted_key
; n
++) {
992 _cleanup_(pkcs11_callback_data_release
) struct pkcs11_callback_data data
= {
995 .encrypted_key
= h
->pkcs11_encrypted_key
+ n
,
998 r
= pkcs11_find_token(data
.encrypted_key
->uri
, pkcs11_callback
, &data
);
1004 r
= test_password_one(data
.encrypted_key
->hashed_password
, data
.decrypted_password
);
1006 return log_error_errno(r
, "Failed to test PKCS#11 password: %m");
1008 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Decrypted password from token is not correct, refusing.");
1010 if (ret_effective_passwords
) {
1011 r
= strv_extend(&effective
, data
.decrypted_password
);
1016 r
= strv_extend(&cache
->pkcs11_passwords
, data
.decrypted_password
);
1024 for (n
= 0; n
< h
->n_fido2_hmac_salt
; n
++) {
1026 _cleanup_(erase_and_freep
) char *decrypted_password
= NULL
;
1028 r
= fido2_use_token(h
, h
, h
->fido2_hmac_salt
+ n
, &decrypted_password
);
1032 r
= test_password_one(h
->fido2_hmac_salt
[n
].hashed_password
, decrypted_password
);
1034 return log_error_errno(r
, "Failed to test FIDO2 password: %m");
1036 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Decrypted password from token is not correct, refusing.");
1038 if (ret_effective_passwords
) {
1039 r
= strv_extend(&effective
, decrypted_password
);
1044 r
= strv_extend(&cache
->fido2_passwords
, decrypted_password
);
1052 if (ret_effective_passwords
)
1053 *ret_effective_passwords
= TAKE_PTR(effective
);
1058 static int determine_default_storage(UserStorage
*ret
) {
1059 UserStorage storage
= _USER_STORAGE_INVALID
;
1065 /* homed tells us via an environment variable which default storage to use */
1066 e
= getenv("SYSTEMD_HOME_DEFAULT_STORAGE");
1068 storage
= user_storage_from_string(e
);
1070 log_warning("$SYSTEMD_HOME_DEFAULT_STORAGE set to invalid storage type, ignoring: %s", e
);
1072 log_info("Using configured default storage '%s'.", user_storage_to_string(storage
));
1078 /* When neither user nor admin specified the storage type to use, fix it to be LUKS — unless we run
1079 * in a container where loopback devices and LUKS/DM are not available. Also, if /home is encrypted
1080 * anyway, let's avoid duplicate encryption. Note that we typically default to the assumption of
1081 * "classic" storage for most operations. However, if we create a new home, then let's user LUKS if
1082 * nothing is specified. */
1084 r
= detect_container();
1086 return log_error_errno(r
, "Failed to determine whether we are in a container: %m");
1088 r
= path_is_encrypted("/home");
1090 log_warning_errno(r
, "Failed to determine if /home is encrypted, ignoring: %m");
1092 log_info("Using automatic default storage of '%s'.", user_storage_to_string(USER_LUKS
));
1097 log_info("/home is encrypted, not using '%s' storage, in order to avoid double encryption.", user_storage_to_string(USER_LUKS
));
1099 log_info("Running in container, not using '%s' storage.", user_storage_to_string(USER_LUKS
));
1101 r
= path_is_fs_type("/home", BTRFS_SUPER_MAGIC
);
1103 log_warning_errno(r
, "Failed to determine file system of /home, ignoring: %m");
1105 log_info("/home is on btrfs, using '%s' as storage.", user_storage_to_string(USER_SUBVOLUME
));
1106 *ret
= USER_SUBVOLUME
;
1108 log_info("/home is on simple file system, using '%s' as storage.", user_storage_to_string(USER_DIRECTORY
));
1109 *ret
= USER_DIRECTORY
;
1115 static int home_create(UserRecord
*h
, UserRecord
**ret_home
) {
1116 _cleanup_(strv_free_erasep
) char **effective_passwords
= NULL
;
1117 _cleanup_(user_record_unrefp
) UserRecord
*new_home
= NULL
;
1118 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1119 UserStorage new_storage
= _USER_STORAGE_INVALID
;
1120 const char *new_fs
= NULL
;
1126 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks name, refusing.");
1127 if (!uid_is_valid(h
->uid
))
1128 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks UID, refusing.");
1130 r
= user_record_compile_effective_passwords(h
, &cache
, &effective_passwords
);
1134 r
= user_record_test_home_directory_and_warn(h
);
1137 if (r
!= USER_TEST_ABSENT
)
1138 return log_error_errno(SYNTHETIC_ERRNO(EEXIST
), "Home directory %s already exists, refusing.", user_record_home_directory(h
));
1140 if (h
->storage
< 0) {
1141 r
= determine_default_storage(&new_storage
);
1146 if ((h
->storage
== USER_LUKS
||
1147 (h
->storage
< 0 && new_storage
== USER_LUKS
)) &&
1148 !h
->file_system_type
)
1149 new_fs
= getenv("SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE");
1151 if (new_storage
>= 0 || new_fs
) {
1152 r
= user_record_add_binding(
1167 return log_error_errno(r
, "Failed to change storage type to LUKS: %m");
1170 r
= user_record_test_image_path_and_warn(h
);
1173 if (!IN_SET(r
, USER_TEST_ABSENT
, USER_TEST_UNDEFINED
, USER_TEST_MAYBE
))
1174 return log_error_errno(SYNTHETIC_ERRNO(EEXIST
), "Image path %s already exists, refusing.", user_record_image_path(h
));
1176 switch (user_record_storage(h
)) {
1179 r
= home_create_luks(h
, &cache
, effective_passwords
, &new_home
);
1182 case USER_DIRECTORY
:
1183 case USER_SUBVOLUME
:
1184 r
= home_create_directory_or_subvolume(h
, &new_home
);
1188 r
= home_create_fscrypt(h
, effective_passwords
, &new_home
);
1192 r
= home_create_cifs(h
, &new_home
);
1196 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
),
1197 "Creating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1202 if (user_record_equal(h
, new_home
)) {
1207 *ret_home
= TAKE_PTR(new_home
);
1211 static int home_remove(UserRecord
*h
) {
1212 bool deleted
= false;
1213 const char *ip
, *hd
;
1219 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks user name, refusing.");
1220 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
1221 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Removing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1223 hd
= user_record_home_directory(h
);
1225 r
= user_record_test_home_directory_and_warn(h
);
1228 if (r
== USER_TEST_MOUNTED
)
1229 return log_error_errno(SYNTHETIC_ERRNO(EBUSY
), "Directory %s is still mounted, refusing.", hd
);
1233 r
= user_record_test_image_path_and_warn(h
);
1237 ip
= user_record_image_path(h
);
1239 switch (user_record_storage(h
)) {
1246 if (stat(ip
, &st
) < 0) {
1247 if (errno
!= ENOENT
)
1248 return log_error_errno(errno
, "Failed to stat() %s: %m", ip
);
1251 if (S_ISREG(st
.st_mode
)) {
1252 if (unlink(ip
) < 0) {
1253 if (errno
!= ENOENT
)
1254 return log_error_errno(errno
, "Failed to remove %s: %m", ip
);
1258 } else if (S_ISBLK(st
.st_mode
))
1259 log_info("Not removing file system on block device %s.", ip
);
1261 return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK
), "Image file %s is neither block device, nor regular, refusing removal.", ip
);
1267 case USER_SUBVOLUME
:
1268 case USER_DIRECTORY
:
1272 r
= rm_rf(ip
, REMOVE_ROOT
|REMOVE_PHYSICAL
|REMOVE_SUBVOLUME
);
1275 return log_warning_errno(r
, "Failed to remove %s: %m", ip
);
1279 /* If the image path and the home directory are the same invalidate the home directory, so
1280 * that we don't remove it anymore */
1281 if (path_equal(ip
, hd
))
1287 /* Nothing else to do here: we won't remove remote stuff. */
1288 log_info("Not removing home directory on remote server.");
1292 assert_not_reached("unknown storage type");
1296 if (rmdir(hd
) < 0) {
1297 if (errno
!= ENOENT
)
1298 return log_error_errno(errno
, "Failed to remove %s, ignoring: %m", hd
);
1304 log_info("Everything completed.");
1306 return log_notice_errno(SYNTHETIC_ERRNO(EALREADY
),
1307 "Nothing to remove.");
1312 static int home_validate_update(UserRecord
*h
, HomeSetup
*setup
) {
1313 bool has_mount
= false;
1320 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks user name, refusing.");
1321 if (!uid_is_valid(h
->uid
))
1322 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks UID, refusing.");
1323 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
1324 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1326 r
= user_record_test_home_directory_and_warn(h
);
1330 has_mount
= r
== USER_TEST_MOUNTED
;
1332 r
= user_record_test_image_path_and_warn(h
);
1335 if (r
== USER_TEST_ABSENT
)
1336 return log_error_errno(SYNTHETIC_ERRNO(ENOENT
), "Image path %s does not exist", user_record_image_path(h
));
1338 switch (user_record_storage(h
)) {
1340 case USER_DIRECTORY
:
1341 case USER_SUBVOLUME
:
1347 r
= home_validate_update_luks(h
, setup
);
1350 if ((r
> 0) != has_mount
)
1351 return log_error_errno(SYNTHETIC_ERRNO(EBUSY
), "Home mount incompletely set up.");
1357 assert_not_reached("unexpected storage type");
1360 return has_mount
; /* return true if the home record is already active */
1363 static int home_update(UserRecord
*h
, UserRecord
**ret
) {
1364 _cleanup_(user_record_unrefp
) UserRecord
*new_home
= NULL
, *header_home
= NULL
, *embedded_home
= NULL
;
1365 _cleanup_(home_setup_undo
) HomeSetup setup
= HOME_SETUP_INIT
;
1366 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1367 bool already_activated
= false;
1373 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ true);
1376 assert(r
> 0); /* Insist that a password was verified */
1378 r
= home_validate_update(h
, &setup
);
1382 already_activated
= r
> 0;
1384 r
= home_prepare(h
, already_activated
, &cache
, &setup
, &header_home
);
1388 r
= home_load_embedded_identity(h
, setup
.root_fd
, header_home
, USER_RECONCILE_REQUIRE_NEWER
, &cache
, &embedded_home
, &new_home
);
1392 r
= home_store_header_identity_luks(new_home
, &setup
, header_home
);
1396 r
= home_store_embedded_identity(new_home
, setup
.root_fd
, h
->uid
, embedded_home
);
1400 r
= home_extend_embedded_identity(new_home
, h
, &setup
);
1404 r
= home_sync_and_statfs(setup
.root_fd
, NULL
);
1408 r
= home_setup_undo(&setup
);
1412 log_info("Everything completed.");
1414 *ret
= TAKE_PTR(new_home
);
1418 static int home_resize(UserRecord
*h
, UserRecord
**ret
) {
1419 _cleanup_(home_setup_undo
) HomeSetup setup
= HOME_SETUP_INIT
;
1420 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1421 bool already_activated
= false;
1427 if (h
->disk_size
== UINT64_MAX
)
1428 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "No target size specified, refusing.");
1430 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ true);
1433 assert(r
> 0); /* Insist that a password was verified */
1435 r
= home_validate_update(h
, &setup
);
1439 already_activated
= r
> 0;
1441 switch (user_record_storage(h
)) {
1444 return home_resize_luks(h
, already_activated
, &cache
, &setup
, ret
);
1446 case USER_DIRECTORY
:
1447 case USER_SUBVOLUME
:
1449 return home_resize_directory(h
, already_activated
, &cache
, &setup
, ret
);
1452 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Resizing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1456 static int home_passwd(UserRecord
*h
, UserRecord
**ret_home
) {
1457 _cleanup_(user_record_unrefp
) UserRecord
*header_home
= NULL
, *embedded_home
= NULL
, *new_home
= NULL
;
1458 _cleanup_(strv_free_erasep
) char **effective_passwords
= NULL
;
1459 _cleanup_(home_setup_undo
) HomeSetup setup
= HOME_SETUP_INIT
;
1460 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1461 bool already_activated
= false;
1467 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
))
1468 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
)));
1470 r
= user_record_compile_effective_passwords(h
, &cache
, &effective_passwords
);
1474 r
= home_validate_update(h
, &setup
);
1478 already_activated
= r
> 0;
1480 r
= home_prepare(h
, already_activated
, &cache
, &setup
, &header_home
);
1484 r
= home_load_embedded_identity(h
, setup
.root_fd
, header_home
, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL
, &cache
, &embedded_home
, &new_home
);
1488 switch (user_record_storage(h
)) {
1491 r
= home_passwd_luks(h
, &setup
, &cache
, effective_passwords
);
1497 r
= home_passwd_fscrypt(h
, &setup
, &cache
, effective_passwords
);
1506 r
= home_store_header_identity_luks(new_home
, &setup
, header_home
);
1510 r
= home_store_embedded_identity(new_home
, setup
.root_fd
, h
->uid
, embedded_home
);
1514 r
= home_extend_embedded_identity(new_home
, h
, &setup
);
1518 r
= home_sync_and_statfs(setup
.root_fd
, NULL
);
1522 r
= home_setup_undo(&setup
);
1526 log_info("Everything completed.");
1528 *ret_home
= TAKE_PTR(new_home
);
1532 static int home_inspect(UserRecord
*h
, UserRecord
**ret_home
) {
1533 _cleanup_(user_record_unrefp
) UserRecord
*header_home
= NULL
, *new_home
= NULL
;
1534 _cleanup_(home_setup_undo
) HomeSetup setup
= HOME_SETUP_INIT
;
1535 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1536 bool already_activated
= false;
1542 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ false);
1546 r
= home_validate_update(h
, &setup
);
1550 already_activated
= r
> 0;
1552 r
= home_prepare(h
, already_activated
, &cache
, &setup
, &header_home
);
1556 r
= home_load_embedded_identity(h
, setup
.root_fd
, header_home
, USER_RECONCILE_ANY
, &cache
, NULL
, &new_home
);
1560 r
= home_extend_embedded_identity(new_home
, h
, &setup
);
1564 r
= home_setup_undo(&setup
);
1568 log_info("Everything completed.");
1570 *ret_home
= TAKE_PTR(new_home
);
1574 static int home_lock(UserRecord
*h
) {
1580 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record incomplete, refusing.");
1581 if (user_record_storage(h
) != USER_LUKS
)
1582 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Locking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1584 r
= user_record_test_home_directory_and_warn(h
);
1587 if (r
!= USER_TEST_MOUNTED
)
1588 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC
), "Home directory of %s is not mounted, can't lock.", h
->user_name
);
1590 r
= home_lock_luks(h
);
1594 log_info("Everything completed.");
1598 static int home_unlock(UserRecord
*h
) {
1599 _cleanup_(password_cache_free
) PasswordCache cache
= {};
1605 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record incomplete, refusing.");
1606 if (user_record_storage(h
) != USER_LUKS
)
1607 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Unlocking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1609 /* Note that we don't check if $HOME is actually mounted, since we want to avoid disk accesses on
1610 * that mount until we have resumed the device. */
1612 r
= user_record_authenticate(h
, h
, &cache
, /* strict_verify= */ false);
1616 r
= home_unlock_luks(h
, &cache
);
1620 log_info("Everything completed.");
1624 static int run(int argc
, char *argv
[]) {
1625 _cleanup_(user_record_unrefp
) UserRecord
*home
= NULL
, *new_home
= NULL
;
1626 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
1627 _cleanup_(fclosep
) FILE *opened_file
= NULL
;
1628 unsigned line
= 0, column
= 0;
1629 const char *json_path
= NULL
;
1634 start
= now(CLOCK_MONOTONIC
);
1636 log_setup_service();
1640 if (argc
< 2 || argc
> 3)
1641 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "This program takes one or two arguments.");
1644 json_path
= argv
[2];
1646 opened_file
= fopen(json_path
, "re");
1648 return log_error_errno(errno
, "Failed to open %s: %m", json_path
);
1650 json_file
= opened_file
;
1652 json_path
= "<stdin>";
1656 r
= json_parse_file(json_file
, json_path
, JSON_PARSE_SENSITIVE
, &v
, &line
, &column
);
1658 return log_error_errno(r
, "[%s:%u:%u] Failed to parse JSON data: %m", json_path
, line
, column
);
1660 home
= user_record_new();
1664 r
= user_record_load(home
, v
, USER_RECORD_LOAD_FULL
|USER_RECORD_LOG
);
1668 /* Well known return values of these operations, that systemd-homed knows and converts to proper D-Bus errors:
1670 * EMSGSIZE → file systems of this type cannot be shrunk
1671 * ETXTBSY → file systems of this type can only be shrunk offline
1672 * ERANGE → file system size too small
1673 * ENOLINK → system does not support selected storage backend
1674 * EPROTONOSUPPORT → system does not support selected file system
1675 * ENOTTY → operation not support on this storage
1676 * ESOCKTNOSUPPORT → operation not support on this file system
1677 * ENOKEY → password incorrect (or not sufficient, or not supplied)
1678 * EREMOTEIO → recovery key incorrect (or not sufficeint, or not supplied — only if no passwords defined)
1679 * EBADSLT → similar, but PKCS#11 device is defined and might be able to provide password, if it was plugged in which it is not
1680 * ENOANO → suitable PKCS#11/FIDO2 device found, but PIN is missing to unlock it
1681 * ERFKILL → suitable PKCS#11 device found, but OK to ask for on-device interactive authentication not given
1682 * EMEDIUMTYPE → suitable FIDO2 device found, but OK to ask for user presence not given
1683 * ENOSTR → suitable FIDO2 device found, but user didn't react to action request on token quickly enough
1684 * EOWNERDEAD → suitable PKCS#11/FIDO2 device found, but its PIN is locked
1685 * ENOLCK → suitable PKCS#11/FIDO2 device found, but PIN incorrect
1686 * ETOOMANYREFS → suitable PKCS#11 device found, but PIN incorrect, and only few tries left
1687 * EUCLEAN → suitable PKCS#11 device found, but PIN incorrect, and only one try left
1688 * EBUSY → file system is currently active
1689 * ENOEXEC → file system is currently not active
1690 * ENOSPC → not enough disk space for operation
1691 * EKEYREVOKED → user record has not suitable hashed password or pkcs#11 entry, we cannot authenticate
1694 if (streq(argv
[1], "activate"))
1695 r
= home_activate(home
, &new_home
);
1696 else if (streq(argv
[1], "deactivate"))
1697 r
= home_deactivate(home
, false);
1698 else if (streq(argv
[1], "deactivate-force"))
1699 r
= home_deactivate(home
, true);
1700 else if (streq(argv
[1], "create"))
1701 r
= home_create(home
, &new_home
);
1702 else if (streq(argv
[1], "remove"))
1703 r
= home_remove(home
);
1704 else if (streq(argv
[1], "update"))
1705 r
= home_update(home
, &new_home
);
1706 else if (streq(argv
[1], "resize"))
1707 r
= home_resize(home
, &new_home
);
1708 else if (streq(argv
[1], "passwd"))
1709 r
= home_passwd(home
, &new_home
);
1710 else if (streq(argv
[1], "inspect"))
1711 r
= home_inspect(home
, &new_home
);
1712 else if (streq(argv
[1], "lock"))
1713 r
= home_lock(home
);
1714 else if (streq(argv
[1], "unlock"))
1715 r
= home_unlock(home
);
1717 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Unknown verb '%s'.", argv
[1]);
1718 if (IN_SET(r
, -ENOKEY
, -EREMOTEIO
) && !strv_isempty(home
->password
) ) { /* There were passwords specified but they were incorrect */
1721 /* Make sure bad password replies always take at least 3s, and if longer multiples of 3s, so
1722 * that it's not clear how long we actually needed for our calculations. */
1723 n
= now(CLOCK_MONOTONIC
);
1726 d
= usec_sub_unsigned(n
, start
);
1727 if (d
> BAD_PASSWORD_DELAY_USEC
)
1728 end
= start
+ DIV_ROUND_UP(d
, BAD_PASSWORD_DELAY_USEC
) * BAD_PASSWORD_DELAY_USEC
;
1730 end
= start
+ BAD_PASSWORD_DELAY_USEC
;
1733 (void) usleep(usec_sub_unsigned(end
, n
));
1738 /* We always pass the new record back, regardless if it changed or not. This allows our caller to
1739 * prepare a fresh record, send to us, and only if it works use it without having to keep a local
1742 json_variant_dump(new_home
->json
, JSON_FORMAT_NEWLINE
, stdout
, NULL
);
1747 DEFINE_MAIN_FUNCTION(run
);