1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include "chown-recursive.h"
10 #include "home-util.h"
11 #include "homework-cifs.h"
12 #include "homework-directory.h"
13 #include "homework-fscrypt.h"
14 #include "homework-luks.h"
15 #include "homework-mount.h"
16 #include "homework-pkcs11.h"
18 #include "main-func.h"
19 #include "memory-util.h"
20 #include "missing_magic.h"
21 #include "mount-util.h"
22 #include "path-util.h"
23 #include "pkcs11-util.h"
25 #include "stat-util.h"
27 #include "tmpfile-util.h"
28 #include "user-util.h"
31 /* Make sure a bad password always results in a 3s delay, no matter what */
32 #define BAD_PASSWORD_DELAY_USEC (3 * USEC_PER_SEC)
34 int user_record_authenticate(
37 char ***pkcs11_decrypted_passwords
) {
39 bool need_password
= false, need_token
= false, need_pin
= false, need_protected_authentication_path_permitted
= false,
40 pin_locked
= false, pin_incorrect
= false, pin_incorrect_few_tries_left
= false, pin_incorrect_one_try_left
= false;
46 /* Tries to authenticate a user record with the supplied secrets. i.e. checks whether at least one
47 * supplied plaintext passwords matches a hashed password field of the user record. Or if a
48 * configured PKCS#11 token is around and can unlock the record.
50 * Note that the pkcs11_decrypted_passwords parameter is both an input and and output parameter: it
51 * is a list of configured, decrypted PKCS#11 passwords. We typically have to call this function
52 * multiple times over the course of an operation (think: on login we authenticate the host user
53 * record, the record embedded in the LUKS record and the one embedded in $HOME). Hence we keep a
54 * list of passwords we already decrypted, so that we don't have to do the (slow an potentially
55 * interactive) PKCS#11 dance for the relevant token again and again. */
57 /* First, let's see if the supplied plain-text passwords work? */
58 r
= user_record_test_secret(h
, secret
);
60 log_info_errno(r
, "None of the supplied plaintext passwords unlocks the user record's hashed passwords.");
62 } else if (r
== -ENXIO
)
63 log_debug_errno(r
, "User record has no hashed passwords, plaintext passwords not tested.");
65 return log_error_errno(r
, "Failed to validate password of record: %m");
67 log_info("Provided password unlocks user record.");
71 /* Second, let's see if any of the PKCS#11 security tokens are plugged in and help us */
72 for (size_t n
= 0; n
< h
->n_pkcs11_encrypted_key
; n
++) {
74 _cleanup_(pkcs11_callback_data_release
) struct pkcs11_callback_data data
= {
77 .encrypted_key
= h
->pkcs11_encrypted_key
+ n
,
81 /* See if any of the previously calculated passwords work */
82 STRV_FOREACH(pp
, *pkcs11_decrypted_passwords
) {
83 r
= test_password_one(data
.encrypted_key
->hashed_password
, *pp
);
85 return log_error_errno(r
, "Failed to check supplied PKCS#11 password: %m");
87 log_info("Previously acquired PKCS#11 password unlocks user record.");
92 r
= pkcs11_find_token(data
.encrypted_key
->uri
, pkcs11_callback
, &data
);
101 need_protected_authentication_path_permitted
= true;
107 pin_incorrect
= true;
110 pin_incorrect
= pin_incorrect_few_tries_left
= true;
113 pin_incorrect
= pin_incorrect_few_tries_left
= pin_incorrect_one_try_left
= true;
119 r
= test_password_one(data
.encrypted_key
->hashed_password
, data
.decrypted_password
);
121 return log_error_errno(r
, "Failed to test PKCS#11 password: %m");
123 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Configured PKCS#11 security token %s does not decrypt encrypted key correctly.", data
.encrypted_key
->uri
);
125 log_info("Decrypted password from PKCS#11 security token %s unlocks user record.", data
.encrypted_key
->uri
);
127 r
= strv_extend(pkcs11_decrypted_passwords
, data
.decrypted_password
);
139 /* Ordered by "relevance", i.e. the most "important" or "interesting" error condition is returned. */
140 if (pin_incorrect_one_try_left
)
142 if (pin_incorrect_few_tries_left
)
143 return -ETOOMANYREFS
;
148 if (need_protected_authentication_path_permitted
)
157 /* Hmm, this means neither PCKS#11 nor classic hashed passwords were supplied, we cannot authenticate this reasonably */
158 return log_debug_errno(SYNTHETIC_ERRNO(EKEYREVOKED
), "No hashed passwords and no PKCS#11 tokens defined, cannot authenticate user record.");
161 int home_setup_undo(HomeSetup
*setup
) {
166 if (setup
->root_fd
>= 0) {
167 if (setup
->do_offline_fitrim
) {
168 q
= run_fitrim(setup
->root_fd
);
173 setup
->root_fd
= safe_close(setup
->root_fd
);
176 if (setup
->undo_mount
) {
177 q
= umount_verbose("/run/systemd/user-home-mount");
182 if (setup
->undo_dm
&& setup
->crypt_device
&& setup
->dm_name
) {
183 q
= crypt_deactivate(setup
->crypt_device
, setup
->dm_name
);
188 if (setup
->image_fd
>= 0) {
189 if (setup
->do_offline_fallocate
) {
190 q
= run_fallocate(setup
->image_fd
, NULL
);
195 setup
->image_fd
= safe_close(setup
->image_fd
);
198 setup
->undo_mount
= false;
199 setup
->undo_dm
= false;
200 setup
->do_offline_fitrim
= false;
201 setup
->do_offline_fallocate
= false;
203 setup
->dm_name
= mfree(setup
->dm_name
);
204 setup
->dm_node
= mfree(setup
->dm_node
);
206 setup
->loop
= loop_device_unref(setup
->loop
);
207 crypt_free(setup
->crypt_device
);
208 setup
->crypt_device
= NULL
;
210 explicit_bzero_safe(setup
->volume_key
, setup
->volume_key_size
);
211 setup
->volume_key
= mfree(setup
->volume_key
);
212 setup
->volume_key_size
= 0;
219 bool already_activated
,
220 char ***pkcs11_decrypted_passwords
,
222 UserRecord
**ret_header_home
) {
228 assert(!setup
->loop
);
229 assert(!setup
->crypt_device
);
230 assert(setup
->root_fd
< 0);
231 assert(!setup
->undo_dm
);
232 assert(!setup
->undo_mount
);
234 /* Makes a home directory accessible (through the root_fd file descriptor, not by path!). */
236 switch (user_record_storage(h
)) {
239 return home_prepare_luks(h
, already_activated
, NULL
, pkcs11_decrypted_passwords
, setup
, ret_header_home
);
243 r
= home_prepare_directory(h
, already_activated
, setup
);
247 r
= home_prepare_fscrypt(h
, already_activated
, pkcs11_decrypted_passwords
, setup
);
251 r
= home_prepare_cifs(h
, already_activated
, setup
);
255 return log_error_errno(SYNTHETIC_ERRNO(ENOLINK
), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
262 *ret_header_home
= NULL
;
267 int home_sync_and_statfs(int root_fd
, struct statfs
*ret
) {
268 assert(root_fd
>= 0);
270 /* Let's sync this to disk, so that the disk space reported by fstatfs() below is accurate (for file
271 * systems such as btrfs where this is determined lazily). */
273 if (syncfs(root_fd
) < 0)
274 return log_error_errno(errno
, "Failed to synchronize file system: %m");
277 if (fstatfs(root_fd
, ret
) < 0)
278 return log_error_errno(errno
, "Failed to statfs() file system: %m");
280 log_info("Synchronized disk.");
285 static int read_identity_file(int root_fd
, JsonVariant
**ret
) {
286 _cleanup_(fclosep
) FILE *identity_file
= NULL
;
287 _cleanup_close_
int identity_fd
= -1;
288 unsigned line
, column
;
291 assert(root_fd
>= 0);
294 identity_fd
= openat(root_fd
, ".identity", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
|O_NONBLOCK
);
296 return log_error_errno(errno
, "Failed to open .identity file in home directory: %m");
298 r
= fd_verify_regular(identity_fd
);
300 return log_error_errno(r
, "Embedded identity file is not a regular file, refusing: %m");
302 identity_file
= take_fdopen(&identity_fd
, "r");
306 r
= json_parse_file(identity_file
, ".identity", JSON_PARSE_SENSITIVE
, ret
, &line
, &column
);
308 return log_error_errno(r
, "[.identity:%u:%u] Failed to parse JSON data: %m", line
, column
);
310 log_info("Read embedded .identity file.");
315 static int write_identity_file(int root_fd
, JsonVariant
*v
, uid_t uid
) {
316 _cleanup_(json_variant_unrefp
) JsonVariant
*normalized
= NULL
;
317 _cleanup_(fclosep
) FILE *identity_file
= NULL
;
318 _cleanup_close_
int identity_fd
= -1;
319 _cleanup_free_
char *fn
= NULL
;
322 assert(root_fd
>= 0);
325 normalized
= json_variant_ref(v
);
327 r
= json_variant_normalize(&normalized
);
329 log_warning_errno(r
, "Failed to normalize user record, ignoring: %m");
331 r
= tempfn_random(".identity", NULL
, &fn
);
335 identity_fd
= openat(root_fd
, fn
, O_WRONLY
|O_CREAT
|O_EXCL
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
, 0600);
337 return log_error_errno(errno
, "Failed to create .identity file in home directory: %m");
339 identity_file
= take_fdopen(&identity_fd
, "w");
340 if (!identity_file
) {
345 json_variant_dump(normalized
, JSON_FORMAT_PRETTY
, identity_file
, NULL
);
347 r
= fflush_and_check(identity_file
);
349 log_error_errno(r
, "Failed to write .identity file: %m");
353 if (fchown(fileno(identity_file
), uid
, uid
) < 0) {
354 log_error_errno(r
, "Failed to change ownership of identity file: %m");
358 if (renameat(root_fd
, fn
, root_fd
, ".identity") < 0) {
359 r
= log_error_errno(errno
, "Failed to move identity file into place: %m");
363 log_info("Wrote embedded .identity file.");
368 (void) unlinkat(root_fd
, fn
, 0);
372 int home_load_embedded_identity(
375 UserRecord
*header_home
,
376 UserReconcileMode mode
,
377 char ***pkcs11_decrypted_passwords
,
378 UserRecord
**ret_embedded_home
,
379 UserRecord
**ret_new_home
) {
381 _cleanup_(user_record_unrefp
) UserRecord
*embedded_home
= NULL
, *intermediate_home
= NULL
, *new_home
= NULL
;
382 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
386 assert(root_fd
>= 0);
388 r
= read_identity_file(root_fd
, &v
);
392 embedded_home
= user_record_new();
396 r
= user_record_load(embedded_home
, v
, USER_RECORD_LOAD_EMBEDDED
);
400 if (!user_record_compatible(h
, embedded_home
))
401 return log_error_errno(SYNTHETIC_ERRNO(EREMCHG
), "Embedded home record not compatible with host record, refusing.");
403 /* Insist that credentials the user supplies also unlocks any embedded records. */
404 r
= user_record_authenticate(embedded_home
, h
, pkcs11_decrypted_passwords
);
408 /* At this point we have three records to deal with:
410 * · The record we got passed from the host
411 * · The record included in the LUKS header (only if LUKS is used)
412 * · The record in the home directory itself (~.identity)
414 * Now we have to reconcile all three, and let the newest one win. */
417 /* Note we relax the requirements here. Instead of insisting that the host record is strictly
418 * newer, let's also be OK if its equally new. If it is, we'll however insist that the
419 * embedded record must be newer, so that we update at least one of the two. */
421 r
= user_record_reconcile(h
, header_home
, mode
== USER_RECONCILE_REQUIRE_NEWER
? USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL
: mode
, &intermediate_home
);
422 if (r
== -EREMCHG
) /* this was supposed to be checked earlier already, but let's check this again */
423 return log_error_errno(r
, "Identity stored on host and in header don't match, refusing.");
425 return log_error_errno(r
, "Embedded identity record is newer than supplied record, refusing.");
427 return log_error_errno(r
, "Failed to reconcile host and header identities: %m");
428 if (r
== USER_RECONCILE_EMBEDDED_WON
)
429 log_info("Reconciling header user identity completed (header version was newer).");
430 else if (r
== USER_RECONCILE_HOST_WON
) {
431 log_info("Reconciling header user identity completed (host version was newer).");
433 if (mode
== USER_RECONCILE_REQUIRE_NEWER
) /* Host version is newer than the header
434 * version, hence we'll update
435 * something. This means we can relax the
436 * requirements on the embedded
438 mode
= USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL
;
440 assert(r
== USER_RECONCILE_IDENTICAL
);
441 log_info("Reconciling user identities completed (host and header version were identical).");
444 h
= intermediate_home
;
447 r
= user_record_reconcile(h
, embedded_home
, mode
, &new_home
);
449 return log_error_errno(r
, "Identity stored on host and in home don't match, refusing.");
451 return log_error_errno(r
, "Embedded identity record is equally new or newer than supplied record, refusing.");
453 return log_error_errno(r
, "Failed to reconcile host and embedded identities: %m");
454 if (r
== USER_RECONCILE_EMBEDDED_WON
)
455 log_info("Reconciling embedded user identity completed (embedded version was newer).");
456 else if (r
== USER_RECONCILE_HOST_WON
)
457 log_info("Reconciling embedded user identity completed (host version was newer).");
459 assert(r
== USER_RECONCILE_IDENTICAL
);
460 log_info("Reconciling embedded user identity completed (host and embedded version were identical).");
463 if (ret_embedded_home
)
464 *ret_embedded_home
= TAKE_PTR(embedded_home
);
467 *ret_new_home
= TAKE_PTR(new_home
);
472 int home_store_embedded_identity(UserRecord
*h
, int root_fd
, uid_t uid
, UserRecord
*old_home
) {
473 _cleanup_(user_record_unrefp
) UserRecord
*embedded
= NULL
;
477 assert(root_fd
>= 0);
478 assert(uid_is_valid(uid
));
480 r
= user_record_clone(h
, USER_RECORD_EXTRACT_EMBEDDED
, &embedded
);
482 return log_error_errno(r
, "Failed to determine new embedded record: %m");
484 if (old_home
&& user_record_equal(old_home
, embedded
)) {
485 log_debug("Not updating embedded home record.");
489 /* The identity has changed, let's update it in the image */
490 r
= write_identity_file(root_fd
, embedded
->json
, h
->uid
);
497 static const char *file_system_type_fd(int fd
) {
502 if (fstatfs(fd
, &sfs
) < 0) {
503 log_debug_errno(errno
, "Failed to statfs(): %m");
507 if (is_fs_type(&sfs
, XFS_SB_MAGIC
))
509 if (is_fs_type(&sfs
, EXT4_SUPER_MAGIC
))
511 if (is_fs_type(&sfs
, BTRFS_SUPER_MAGIC
))
517 int home_extend_embedded_identity(UserRecord
*h
, UserRecord
*used
, HomeSetup
*setup
) {
524 r
= user_record_add_binding(
526 user_record_storage(used
),
527 user_record_image_path(used
),
528 setup
->found_partition_uuid
,
529 setup
->found_luks_uuid
,
530 setup
->found_fs_uuid
,
531 setup
->crypt_device
? crypt_get_cipher(setup
->crypt_device
) : NULL
,
532 setup
->crypt_device
? crypt_get_cipher_mode(setup
->crypt_device
) : NULL
,
533 setup
->crypt_device
? luks_volume_key_size_convert(setup
->crypt_device
) : UINT64_MAX
,
534 file_system_type_fd(setup
->root_fd
),
535 user_record_home_directory(used
),
539 return log_error_errno(r
, "Failed to update binding in record: %m");
544 static int chown_recursive_directory(int root_fd
, uid_t uid
) {
547 assert(root_fd
>= 0);
548 assert(uid_is_valid(uid
));
550 r
= fd_chown_recursive(root_fd
, uid
, (gid_t
) uid
, 0777);
552 return log_error_errno(r
, "Failed to change ownership of files and directories: %m");
554 log_info("Recursive changing of ownership not necessary, skipped.");
556 log_info("Recursive changing of ownership completed.");
564 UserRecord
*header_home
,
565 char ***pkcs11_decrypted_passwords
,
566 struct statfs
*ret_statfs
,
567 UserRecord
**ret_new_home
) {
569 _cleanup_(user_record_unrefp
) UserRecord
*embedded_home
= NULL
, *new_home
= NULL
;
574 assert(ret_new_home
);
576 /* When activating a home directory, does the identity work: loads the identity from the $HOME
577 * directory, reconciles it with our idea, chown()s everything. */
579 r
= home_load_embedded_identity(h
, setup
->root_fd
, header_home
, USER_RECONCILE_ANY
, pkcs11_decrypted_passwords
, &embedded_home
, &new_home
);
583 r
= home_store_header_identity_luks(new_home
, setup
, header_home
);
587 r
= home_store_embedded_identity(new_home
, setup
->root_fd
, h
->uid
, embedded_home
);
591 r
= chown_recursive_directory(setup
->root_fd
, h
->uid
);
595 r
= home_sync_and_statfs(setup
->root_fd
, ret_statfs
);
599 *ret_new_home
= TAKE_PTR(new_home
);
603 static int home_activate(UserRecord
*h
, UserRecord
**ret_home
) {
604 _cleanup_(strv_free_erasep
) char **pkcs11_decrypted_passwords
= NULL
;
605 _cleanup_(user_record_unrefp
) UserRecord
*new_home
= NULL
;
611 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks user name, refusing.");
612 if (!uid_is_valid(h
->uid
))
613 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks UID, refusing.");
614 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
615 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Activating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
617 r
= user_record_authenticate(h
, h
, &pkcs11_decrypted_passwords
);
621 r
= user_record_test_home_directory_and_warn(h
);
624 if (r
== USER_TEST_MOUNTED
)
625 return log_error_errno(SYNTHETIC_ERRNO(EALREADY
), "Home directory %s is already mounted, refusing.", user_record_home_directory(h
));
627 r
= user_record_test_image_path_and_warn(h
);
630 if (r
== USER_TEST_ABSENT
)
631 return log_error_errno(SYNTHETIC_ERRNO(ENOENT
), "Image path %s is missing, refusing.", user_record_image_path(h
));
633 switch (user_record_storage(h
)) {
636 r
= home_activate_luks(h
, &pkcs11_decrypted_passwords
, &new_home
);
645 r
= home_activate_directory(h
, &pkcs11_decrypted_passwords
, &new_home
);
652 r
= home_activate_cifs(h
, &pkcs11_decrypted_passwords
, &new_home
);
659 assert_not_reached("unexpected type");
662 /* Note that the returned object might either be a reference to an updated version of the existing
663 * home object, or a reference to a newly allocated home object. The caller has to be able to deal
664 * with both, and consider the old object out-of-date. */
665 if (user_record_equal(h
, new_home
)) {
667 return 0; /* no identity change */
670 *ret_home
= TAKE_PTR(new_home
);
671 return 1; /* identity updated */
674 static int home_deactivate(UserRecord
*h
, bool force
) {
681 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record incomplete, refusing.");
682 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
683 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Deactivating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
685 r
= user_record_test_home_directory_and_warn(h
);
688 if (r
== USER_TEST_MOUNTED
) {
689 if (user_record_storage(h
) == USER_LUKS
) {
690 r
= home_trim_luks(h
);
695 if (umount2(user_record_home_directory(h
), UMOUNT_NOFOLLOW
| (force
? MNT_FORCE
|MNT_DETACH
: 0)) < 0)
696 return log_error_errno(errno
, "Failed to unmount %s: %m", user_record_home_directory(h
));
698 log_info("Unmounting completed.");
701 log_info("Directory %s is already unmounted.", user_record_home_directory(h
));
703 if (user_record_storage(h
) == USER_LUKS
) {
704 r
= home_deactivate_luks(h
);
712 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC
), "Home is not active.");
714 log_info("Everything completed.");
718 static int copy_skel(int root_fd
, const char *skel
) {
721 assert(root_fd
>= 0);
723 r
= copy_tree_at(AT_FDCWD
, skel
, root_fd
, ".", UID_INVALID
, GID_INVALID
, COPY_MERGE
|COPY_REPLACE
);
725 log_info("Skeleton directory %s missing, ignoring.", skel
);
729 return log_error_errno(r
, "Failed to copy in %s: %m", skel
);
731 log_info("Copying in %s completed.", skel
);
735 static int change_access_mode(int root_fd
, mode_t m
) {
736 assert(root_fd
>= 0);
738 if (fchmod(root_fd
, m
) < 0)
739 return log_error_errno(errno
, "Failed to change access mode of top-level directory: %m");
741 log_info("Changed top-level directory access mode to 0%o.", m
);
745 int home_populate(UserRecord
*h
, int dir_fd
) {
751 r
= copy_skel(dir_fd
, user_record_skeleton_directory(h
));
755 r
= home_store_embedded_identity(h
, dir_fd
, h
->uid
, NULL
);
759 r
= chown_recursive_directory(dir_fd
, h
->uid
);
763 r
= change_access_mode(dir_fd
, user_record_access_mode(h
));
770 static int user_record_compile_effective_passwords(
772 char ***ret_effective_passwords
,
773 char ***ret_pkcs11_decrypted_passwords
) {
775 _cleanup_(strv_free_erasep
) char **effective
= NULL
, **pkcs11_passwords
= NULL
;
782 /* We insist on at least one classic hashed password to be defined in addition to any PKCS#11 one, as
783 * a safe fallback, but also to simplify the password changing algorithm: there we require providing
784 * the old literal password only (and do not care for the old PKCS#11 token) */
786 if (strv_isempty(h
->hashed_password
))
787 return log_error_errno(EINVAL
, "User record has no hashed passwords, refusing.");
789 /* Generates the list of plaintext passwords to propagate to LUKS/fscrypt devices, and checks whether
790 * we have a plaintext password for each hashed one. If we are missing one we'll fail, since we
791 * couldn't sync fscrypt/LUKS to the login account properly. */
793 STRV_FOREACH(i
, h
->hashed_password
) {
797 log_debug("Looking for plaintext password for: %s", *i
);
799 /* Let's scan all provided plaintext passwords */
800 STRV_FOREACH(j
, h
->password
) {
801 r
= test_password_one(*i
, *j
);
803 return log_error_errno(r
, "Failed to test plain text password: %m");
805 if (ret_effective_passwords
) {
806 r
= strv_extend(&effective
, *j
);
811 log_debug("Found literal plaintext password.");
818 return log_error_errno(SYNTHETIC_ERRNO(ENOKEY
), "Missing plaintext password for defined hashed password");
821 for (n
= 0; n
< h
->n_pkcs11_encrypted_key
; n
++) {
823 _cleanup_(pkcs11_callback_data_release
) struct pkcs11_callback_data data
= {
826 .encrypted_key
= h
->pkcs11_encrypted_key
+ n
,
829 r
= pkcs11_find_token(data
.encrypted_key
->uri
, pkcs11_callback
, &data
);
835 r
= test_password_one(data
.encrypted_key
->hashed_password
, data
.decrypted_password
);
837 return log_error_errno(r
, "Failed to test PKCS#11 password: %m");
839 return log_error_errno(SYNTHETIC_ERRNO(EPERM
), "Decrypted password from token is not correct, refusing.");
841 if (ret_effective_passwords
) {
842 r
= strv_extend(&effective
, data
.decrypted_password
);
847 if (ret_pkcs11_decrypted_passwords
) {
848 r
= strv_extend(&pkcs11_passwords
, data
.decrypted_password
);
857 if (ret_effective_passwords
)
858 *ret_effective_passwords
= TAKE_PTR(effective
);
859 if (ret_pkcs11_decrypted_passwords
)
860 *ret_pkcs11_decrypted_passwords
= TAKE_PTR(pkcs11_passwords
);
865 static int home_create(UserRecord
*h
, UserRecord
**ret_home
) {
866 _cleanup_(strv_free_erasep
) char **effective_passwords
= NULL
, **pkcs11_decrypted_passwords
= NULL
;
867 _cleanup_(user_record_unrefp
) UserRecord
*new_home
= NULL
;
873 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks name, refusing.");
874 if (!uid_is_valid(h
->uid
))
875 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks UID, refusing.");
877 r
= user_record_compile_effective_passwords(h
, &effective_passwords
, &pkcs11_decrypted_passwords
);
881 r
= user_record_test_home_directory_and_warn(h
);
884 if (r
!= USER_TEST_ABSENT
)
885 return log_error_errno(SYNTHETIC_ERRNO(EEXIST
), "Home directory %s already exists, refusing.", user_record_home_directory(h
));
887 /* When the user didn't specify the storage type to use, fix it to be LUKS -- unless we run in a
888 * container where loopback devices and LUKS/DM are not available. Note that we typically default to
889 * the assumption of "classic" storage for most operations. However, if we create a new home, then
890 * let's user LUKS if nothing is specified. */
891 if (h
->storage
< 0) {
892 UserStorage new_storage
;
894 r
= detect_container();
896 return log_error_errno(r
, "Failed to determine whether we are in a container: %m");
898 new_storage
= USER_DIRECTORY
;
900 r
= path_is_fs_type("/home", BTRFS_SUPER_MAGIC
);
902 log_debug_errno(r
, "Failed to determine file system of /home, ignoring: %m");
904 new_storage
= r
> 0 ? USER_SUBVOLUME
: USER_DIRECTORY
;
906 new_storage
= USER_LUKS
;
908 r
= user_record_add_binding(
923 return log_error_errno(r
, "Failed to change storage type to LUKS: %m");
925 if (!h
->image_path_auto
) {
926 h
->image_path_auto
= strjoin("/home/", user_record_user_name_and_realm(h
), new_storage
== USER_LUKS
? ".home" : ".homedir");
927 if (!h
->image_path_auto
)
932 r
= user_record_test_image_path_and_warn(h
);
935 if (!IN_SET(r
, USER_TEST_ABSENT
, USER_TEST_UNDEFINED
, USER_TEST_MAYBE
))
936 return log_error_errno(SYNTHETIC_ERRNO(EEXIST
), "Image path %s already exists, refusing.", user_record_image_path(h
));
938 switch (user_record_storage(h
)) {
941 r
= home_create_luks(h
, pkcs11_decrypted_passwords
, effective_passwords
, &new_home
);
946 r
= home_create_directory_or_subvolume(h
, &new_home
);
950 r
= home_create_fscrypt(h
, effective_passwords
, &new_home
);
954 r
= home_create_cifs(h
, &new_home
);
958 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
),
959 "Creating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
964 if (user_record_equal(h
, new_home
)) {
969 *ret_home
= TAKE_PTR(new_home
);
973 static int home_remove(UserRecord
*h
) {
974 bool deleted
= false;
981 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks user name, refusing.");
982 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
983 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Removing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
985 hd
= user_record_home_directory(h
);
987 r
= user_record_test_home_directory_and_warn(h
);
990 if (r
== USER_TEST_MOUNTED
)
991 return log_error_errno(SYNTHETIC_ERRNO(EBUSY
), "Directory %s is still mounted, refusing.", hd
);
995 r
= user_record_test_image_path_and_warn(h
);
999 ip
= user_record_image_path(h
);
1001 switch (user_record_storage(h
)) {
1008 if (stat(ip
, &st
) < 0) {
1009 if (errno
!= -ENOENT
)
1010 return log_error_errno(errno
, "Failed to stat() %s: %m", ip
);
1013 if (S_ISREG(st
.st_mode
)) {
1014 if (unlink(ip
) < 0) {
1015 if (errno
!= ENOENT
)
1016 return log_error_errno(errno
, "Failed to remove %s: %m", ip
);
1020 } else if (S_ISBLK(st
.st_mode
))
1021 log_info("Not removing file system on block device %s.", ip
);
1023 return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK
), "Image file %s is neither block device, nor regular, refusing removal.", ip
);
1029 case USER_SUBVOLUME
:
1030 case USER_DIRECTORY
:
1034 r
= rm_rf(ip
, REMOVE_ROOT
|REMOVE_PHYSICAL
|REMOVE_SUBVOLUME
);
1037 return log_warning_errno(r
, "Failed to remove %s: %m", ip
);
1041 /* If the image path and the home directory are the same invalidate the home directory, so
1042 * that we don't remove it anymore */
1043 if (path_equal(ip
, hd
))
1049 /* Nothing else to do here: we won't remove remote stuff. */
1050 log_info("Not removing home directory on remote server.");
1054 assert_not_reached("unknown storage type");
1058 if (rmdir(hd
) < 0) {
1059 if (errno
!= ENOENT
)
1060 return log_error_errno(errno
, "Failed to remove %s, ignoring: %m", hd
);
1066 log_info("Everything completed.");
1068 return log_notice_errno(SYNTHETIC_ERRNO(EALREADY
),
1069 "Nothing to remove.");
1074 static int home_validate_update(UserRecord
*h
, HomeSetup
*setup
) {
1075 bool has_mount
= false;
1082 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks user name, refusing.");
1083 if (!uid_is_valid(h
->uid
))
1084 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record lacks UID, refusing.");
1085 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
, USER_CIFS
))
1086 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1088 r
= user_record_test_home_directory_and_warn(h
);
1092 has_mount
= r
== USER_TEST_MOUNTED
;
1094 r
= user_record_test_image_path_and_warn(h
);
1097 if (r
== USER_TEST_ABSENT
)
1098 return log_error_errno(SYNTHETIC_ERRNO(ENOENT
), "Image path %s does not exist", user_record_image_path(h
));
1100 switch (user_record_storage(h
)) {
1102 case USER_DIRECTORY
:
1103 case USER_SUBVOLUME
:
1109 r
= home_validate_update_luks(h
, setup
);
1112 if ((r
> 0) != has_mount
)
1113 return log_error_errno(SYNTHETIC_ERRNO(EBUSY
), "Home mount incompletely set up.");
1119 assert_not_reached("unexpected storage type");
1122 return has_mount
; /* return true if the home record is already active */
1125 static int home_update(UserRecord
*h
, UserRecord
**ret
) {
1126 _cleanup_(user_record_unrefp
) UserRecord
*new_home
= NULL
, *header_home
= NULL
, *embedded_home
= NULL
;
1127 _cleanup_(strv_free_erasep
) char **pkcs11_decrypted_passwords
= NULL
;
1128 _cleanup_(home_setup_undo
) HomeSetup setup
= HOME_SETUP_INIT
;
1129 bool already_activated
= false;
1135 r
= user_record_authenticate(h
, h
, &pkcs11_decrypted_passwords
);
1139 r
= home_validate_update(h
, &setup
);
1143 already_activated
= r
> 0;
1145 r
= home_prepare(h
, already_activated
, &pkcs11_decrypted_passwords
, &setup
, &header_home
);
1149 r
= home_load_embedded_identity(h
, setup
.root_fd
, header_home
, USER_RECONCILE_REQUIRE_NEWER
, &pkcs11_decrypted_passwords
, &embedded_home
, &new_home
);
1153 r
= home_store_header_identity_luks(new_home
, &setup
, header_home
);
1157 r
= home_store_embedded_identity(new_home
, setup
.root_fd
, h
->uid
, embedded_home
);
1161 r
= home_extend_embedded_identity(new_home
, h
, &setup
);
1165 r
= home_sync_and_statfs(setup
.root_fd
, NULL
);
1169 r
= home_setup_undo(&setup
);
1173 log_info("Everything completed.");
1175 *ret
= TAKE_PTR(new_home
);
1179 static int home_resize(UserRecord
*h
, UserRecord
**ret
) {
1180 _cleanup_(home_setup_undo
) HomeSetup setup
= HOME_SETUP_INIT
;
1181 _cleanup_(strv_free_erasep
) char **pkcs11_decrypted_passwords
= NULL
;
1182 bool already_activated
= false;
1188 if (h
->disk_size
== UINT64_MAX
)
1189 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "No target size specified, refusing.");
1191 r
= user_record_authenticate(h
, h
, &pkcs11_decrypted_passwords
);
1195 r
= home_validate_update(h
, &setup
);
1199 already_activated
= r
> 0;
1201 switch (user_record_storage(h
)) {
1204 return home_resize_luks(h
, already_activated
, &pkcs11_decrypted_passwords
, &setup
, ret
);
1206 case USER_DIRECTORY
:
1207 case USER_SUBVOLUME
:
1209 return home_resize_directory(h
, already_activated
, &pkcs11_decrypted_passwords
, &setup
, ret
);
1212 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Resizing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1216 static int home_passwd(UserRecord
*h
, UserRecord
**ret_home
) {
1217 _cleanup_(user_record_unrefp
) UserRecord
*header_home
= NULL
, *embedded_home
= NULL
, *new_home
= NULL
;
1218 _cleanup_(strv_free_erasep
) char **effective_passwords
= NULL
, **pkcs11_decrypted_passwords
= NULL
;
1219 _cleanup_(home_setup_undo
) HomeSetup setup
= HOME_SETUP_INIT
;
1220 bool already_activated
= false;
1226 if (!IN_SET(user_record_storage(h
), USER_LUKS
, USER_DIRECTORY
, USER_SUBVOLUME
, USER_FSCRYPT
))
1227 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
)));
1229 r
= user_record_compile_effective_passwords(h
, &effective_passwords
, &pkcs11_decrypted_passwords
);
1233 r
= home_validate_update(h
, &setup
);
1237 already_activated
= r
> 0;
1239 r
= home_prepare(h
, already_activated
, &pkcs11_decrypted_passwords
, &setup
, &header_home
);
1243 r
= home_load_embedded_identity(h
, setup
.root_fd
, header_home
, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL
, &pkcs11_decrypted_passwords
, &embedded_home
, &new_home
);
1247 switch (user_record_storage(h
)) {
1250 r
= home_passwd_luks(h
, &setup
, pkcs11_decrypted_passwords
, effective_passwords
);
1256 r
= home_passwd_fscrypt(h
, &setup
, pkcs11_decrypted_passwords
, effective_passwords
);
1265 r
= home_store_header_identity_luks(new_home
, &setup
, header_home
);
1269 r
= home_store_embedded_identity(new_home
, setup
.root_fd
, h
->uid
, embedded_home
);
1273 r
= home_extend_embedded_identity(new_home
, h
, &setup
);
1277 r
= home_sync_and_statfs(setup
.root_fd
, NULL
);
1281 r
= home_setup_undo(&setup
);
1285 log_info("Everything completed.");
1287 *ret_home
= TAKE_PTR(new_home
);
1291 static int home_inspect(UserRecord
*h
, UserRecord
**ret_home
) {
1292 _cleanup_(user_record_unrefp
) UserRecord
*header_home
= NULL
, *new_home
= NULL
;
1293 _cleanup_(home_setup_undo
) HomeSetup setup
= HOME_SETUP_INIT
;
1294 _cleanup_(strv_free_erasep
) char **pkcs11_decrypted_passwords
= NULL
;
1295 bool already_activated
= false;
1301 r
= user_record_authenticate(h
, h
, &pkcs11_decrypted_passwords
);
1305 r
= home_validate_update(h
, &setup
);
1309 already_activated
= r
> 0;
1311 r
= home_prepare(h
, already_activated
, &pkcs11_decrypted_passwords
, &setup
, &header_home
);
1315 r
= home_load_embedded_identity(h
, setup
.root_fd
, header_home
, USER_RECONCILE_ANY
, &pkcs11_decrypted_passwords
, NULL
, &new_home
);
1319 r
= home_extend_embedded_identity(new_home
, h
, &setup
);
1323 r
= home_setup_undo(&setup
);
1327 log_info("Everything completed.");
1329 *ret_home
= TAKE_PTR(new_home
);
1333 static int home_lock(UserRecord
*h
) {
1339 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record incomplete, refusing.");
1340 if (user_record_storage(h
) != USER_LUKS
)
1341 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Locking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1343 r
= user_record_test_home_directory_and_warn(h
);
1346 if (r
!= USER_TEST_MOUNTED
)
1347 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC
), "Home directory of %s is not mounted, can't lock.", h
->user_name
);
1349 r
= home_lock_luks(h
);
1353 log_info("Everything completed.");
1357 static int home_unlock(UserRecord
*h
) {
1358 _cleanup_(strv_free_erasep
) char **pkcs11_decrypted_passwords
= NULL
;
1364 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "User record incomplete, refusing.");
1365 if (user_record_storage(h
) != USER_LUKS
)
1366 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY
), "Unlocking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h
)));
1368 /* Note that we don't check if $HOME is actually mounted, since we want to avoid disk accesses on
1369 * that mount until we have resumed the device. */
1371 r
= user_record_authenticate(h
, h
, &pkcs11_decrypted_passwords
);
1375 r
= home_unlock_luks(h
, &pkcs11_decrypted_passwords
);
1379 log_info("Everything completed.");
1383 static int run(int argc
, char *argv
[]) {
1384 _cleanup_(user_record_unrefp
) UserRecord
*home
= NULL
, *new_home
= NULL
;
1385 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
1386 _cleanup_(fclosep
) FILE *opened_file
= NULL
;
1387 unsigned line
= 0, column
= 0;
1388 const char *json_path
= NULL
;
1393 start
= now(CLOCK_MONOTONIC
);
1395 log_setup_service();
1399 if (argc
< 2 || argc
> 3)
1400 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "This program takes one or two arguments.");
1403 json_path
= argv
[2];
1405 opened_file
= fopen(json_path
, "re");
1407 return log_error_errno(errno
, "Failed to open %s: %m", json_path
);
1409 json_file
= opened_file
;
1411 json_path
= "<stdin>";
1415 r
= json_parse_file(json_file
, json_path
, JSON_PARSE_SENSITIVE
, &v
, &line
, &column
);
1417 return log_error_errno(r
, "[%s:%u:%u] Failed to parse JSON data: %m", json_path
, line
, column
);
1419 home
= user_record_new();
1423 r
= user_record_load(home
, v
, USER_RECORD_LOAD_FULL
|USER_RECORD_LOG
);
1427 /* Well known return values of these operations, that systemd-homed knows and converts to proper D-Bus errors:
1429 * EMSGSIZE → file systems of this type cannot be shrunk
1430 * ETXTBSY → file systems of this type can only be shrunk offline
1431 * ERANGE → file system size too small
1432 * ENOLINK → system does not support selected storage backend
1433 * EPROTONOSUPPORT → system does not support selected file system
1434 * ENOTTY → operation not support on this storage
1435 * ESOCKTNOSUPPORT → operation not support on this file system
1436 * ENOKEY → password incorrect (or not sufficient, or not supplied)
1437 * EBADSLT → similar, but PKCS#11 device is defined and might be able to provide password, if it was plugged in which it is not
1438 * ENOANO → suitable PKCS#11 device found, but PIN is missing to unlock it
1439 * ERFKILL → suitable PKCS#11 device found, but OK to ask for on-device interactive authentication not given
1440 * EOWNERDEAD → suitable PKCS#11 device found, but its PIN is locked
1441 * ENOLCK → suitable PKCS#11 device found, but PIN incorrect
1442 * ETOOMANYREFS → suitable PKCS#11 device found, but PIN incorrect, and only few tries left
1443 * EUCLEAN → suitable PKCS#11 device found, but PIN incorrect, and only one try left
1444 * EBUSY → file system is currently active
1445 * ENOEXEC → file system is currently not active
1446 * ENOSPC → not enough disk space for operation
1449 if (streq(argv
[1], "activate"))
1450 r
= home_activate(home
, &new_home
);
1451 else if (streq(argv
[1], "deactivate"))
1452 r
= home_deactivate(home
, false);
1453 else if (streq(argv
[1], "deactivate-force"))
1454 r
= home_deactivate(home
, true);
1455 else if (streq(argv
[1], "create"))
1456 r
= home_create(home
, &new_home
);
1457 else if (streq(argv
[1], "remove"))
1458 r
= home_remove(home
);
1459 else if (streq(argv
[1], "update"))
1460 r
= home_update(home
, &new_home
);
1461 else if (streq(argv
[1], "resize"))
1462 r
= home_resize(home
, &new_home
);
1463 else if (streq(argv
[1], "passwd"))
1464 r
= home_passwd(home
, &new_home
);
1465 else if (streq(argv
[1], "inspect"))
1466 r
= home_inspect(home
, &new_home
);
1467 else if (streq(argv
[1], "lock"))
1468 r
= home_lock(home
);
1469 else if (streq(argv
[1], "unlock"))
1470 r
= home_unlock(home
);
1472 return log_error_errno(SYNTHETIC_ERRNO(EINVAL
), "Unknown verb '%s'.", argv
[1]);
1473 if (r
== -ENOKEY
&& !strv_isempty(home
->password
)) { /* There were passwords specified but they were incorrect */
1476 /* Make sure bad password replies always take at least 3s, and if longer multiples of 3s, so
1477 * that it's not clear how long we actually needed for our calculations. */
1478 n
= now(CLOCK_MONOTONIC
);
1481 d
= usec_sub_unsigned(n
, start
);
1482 if (d
> BAD_PASSWORD_DELAY_USEC
)
1483 end
= start
+ DIV_ROUND_UP(d
, BAD_PASSWORD_DELAY_USEC
) * BAD_PASSWORD_DELAY_USEC
;
1485 end
= start
+ BAD_PASSWORD_DELAY_USEC
;
1488 (void) usleep(usec_sub_unsigned(end
, n
));
1493 /* We always pass the new record back, regardless if it changed or not. This allows our caller to
1494 * prepare a fresh record, send to us, and only if it works use it without having to keep a local
1497 json_variant_dump(new_home
->json
, JSON_FORMAT_NEWLINE
, stdout
, NULL
);
1502 DEFINE_MAIN_FUNCTION(run
);