diff --git a/src/home/homectl.c b/src/home/homectl.c index cc2b9c8f31..706ce75dfb 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -1535,7 +1535,7 @@ static int home_record_reset_human_interaction_permission(UserRecord *hr) { static int update_home(int argc, char *argv[], void *userdata) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; - _cleanup_(user_record_unrefp) UserRecord *hr = NULL; + _cleanup_(user_record_unrefp) UserRecord *hr = NULL, *secret = NULL; _cleanup_free_ char *buffer = NULL; const char *username; int r; @@ -1561,6 +1561,15 @@ static int update_home(int argc, char *argv[], void *userdata) { if (r < 0) return r; + /* Add in all secrets we can acquire cheaply */ + r = acquire_passed_secrets(username, &secret); + if (r < 0) + return r; + + r = user_record_merge_secret(hr, secret); + if (r < 0) + return r; + /* If we do multiple operations, let's output things more verbosely, since otherwise the repeated * authentication might be confusing. */ @@ -1706,9 +1715,9 @@ static int passwd_home(int argc, char *argv[], void *userdata) { (void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password); - old_secret = user_record_new(); - if (!old_secret) - return log_oom(); + r = acquire_passed_secrets(username, &old_secret); + if (r < 0) + return r; new_secret = user_record_new(); if (!new_secret) diff --git a/src/home/homework-cifs.c b/src/home/homework-cifs.c index b49b7b3dcd..ed06d1f221 100644 --- a/src/home/homework-cifs.c +++ b/src/home/homework-cifs.c @@ -145,6 +145,7 @@ int home_setup_cifs( int home_activate_cifs( UserRecord *h, + HomeSetupFlags flags, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home) { @@ -165,7 +166,7 @@ int home_activate_cifs( if (r < 0) return r; - r = home_refresh(h, setup, header_home, cache, NULL, &new_home); + r = home_refresh(h, flags, setup, header_home, cache, NULL, &new_home); if (r < 0) return r; diff --git a/src/home/homework-cifs.h b/src/home/homework-cifs.h index dda1e0b876..af8c466629 100644 --- a/src/home/homework-cifs.h +++ b/src/home/homework-cifs.h @@ -6,6 +6,6 @@ int home_setup_cifs(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup); -int home_activate_cifs(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home); +int home_activate_cifs(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home); int home_create_cifs(UserRecord *h, HomeSetup *setup, UserRecord **ret_home); diff --git a/src/home/homework-directory.c b/src/home/homework-directory.c index af13fa026a..c2b383b7cd 100644 --- a/src/home/homework-directory.c +++ b/src/home/homework-directory.c @@ -58,6 +58,7 @@ int home_setup_directory(UserRecord *h, HomeSetup *setup) { int home_activate_directory( UserRecord *h, + HomeSetupFlags flags, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home) { @@ -74,11 +75,11 @@ int home_activate_directory( assert_se(hdo = user_record_home_directory(h)); hd = strdupa_safe(hdo); - r = home_setup(h, 0, setup, cache, &header_home); + r = home_setup(h, flags, setup, cache, &header_home); if (r < 0) return r; - r = home_refresh(h, setup, header_home, cache, NULL, &new_home); + r = home_refresh(h, flags, setup, header_home, cache, NULL, &new_home); if (r < 0) return r; @@ -279,7 +280,7 @@ int home_resize_directory( if (r < 0) return r; - r = home_maybe_shift_uid(h, setup); + r = home_maybe_shift_uid(h, flags, setup); if (r < 0) return r; diff --git a/src/home/homework-directory.h b/src/home/homework-directory.h index ecbb2f143c..fe03e5deb1 100644 --- a/src/home/homework-directory.h +++ b/src/home/homework-directory.h @@ -5,6 +5,6 @@ #include "user-record.h" int home_setup_directory(UserRecord *h, HomeSetup *setup); -int home_activate_directory(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home); +int home_activate_directory(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home); int home_create_directory_or_subvolume(UserRecord *h, HomeSetup *setup, UserRecord **ret_home); int home_resize_directory(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home); diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index ac379c6d07..29a18b48d9 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -428,7 +428,7 @@ static int luks_setup( if (r == -ENOKEY) return log_error_errno(r, "No valid password for LUKS superblock."); if (r < 0) - return log_error_errno(r, "Failed to unlocks LUKS superblock: %m"); + return log_error_errno(r, "Failed to unlock LUKS superblock: %m"); r = sym_crypt_activate_by_volume_key( cd, @@ -1511,6 +1511,7 @@ static int home_auto_grow_luks( int home_activate_luks( UserRecord *h, + HomeSetupFlags flags, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home) { @@ -1563,6 +1564,7 @@ int home_activate_luks( r = home_refresh( h, + flags, setup, luks_home_record, cache, @@ -3200,6 +3202,10 @@ int home_resize_luks( return r; } + r = home_maybe_shift_uid(h, flags, setup); + if (r < 0) + return r; + log_info("offset = %" PRIu64 ", size = %" PRIu64 ", image = %" PRIu64, setup->partition_offset, setup->partition_size, old_image_size); if ((UINT64_MAX - setup->partition_offset) < setup->partition_size || diff --git a/src/home/homework-luks.h b/src/home/homework-luks.h index f0f29b78f7..0218de8ccd 100644 --- a/src/home/homework-luks.h +++ b/src/home/homework-luks.h @@ -7,7 +7,7 @@ int home_setup_luks(UserRecord *h, HomeSetupFlags flags, const char *force_image_path, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_luks_home); -int home_activate_luks(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home); +int home_activate_luks(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home); int home_deactivate_luks(UserRecord *h, HomeSetup *setup); int home_trim_luks(UserRecord *h, HomeSetup *setup); diff --git a/src/home/homework-mount.c b/src/home/homework-mount.c index 1e63dbed41..0b028dad37 100644 --- a/src/home/homework-mount.c +++ b/src/home/homework-mount.c @@ -283,6 +283,8 @@ int home_shift_uid(int dir_fd, const char *target, uid_t stored_uid, uid_t expos if (r < 0) return log_error_errno(errno, "Failed to apply UID/GID map: %m"); + log_debug("Applied uidmap mount to %s. Mapping is " UID_FMT " → " UID_FMT ".", strna(target), stored_uid, exposed_uid); + if (ret_mount_fd) *ret_mount_fd = TAKE_FD(mount_fd); diff --git a/src/home/homework.c b/src/home/homework.c index ac52a011ed..520b6b6f06 100644 --- a/src/home/homework.c +++ b/src/home/homework.c @@ -585,7 +585,7 @@ static int write_identity_file(int root_fd, JsonVariant *v, uid_t uid) { } if (fchown(fileno(identity_file), uid, uid) < 0) { - log_error_errno(r, "Failed to change ownership of identity file: %m"); + r = log_error_errno(errno, "Failed to change ownership of identity file: %m"); goto fail; } @@ -788,6 +788,7 @@ static int chown_recursive_directory(int root_fd, uid_t uid) { int home_maybe_shift_uid( UserRecord *h, + HomeSetupFlags flags, HomeSetup *setup) { _cleanup_close_ int mount_fd = -1; @@ -797,6 +798,10 @@ int home_maybe_shift_uid( assert(setup); assert(setup->root_fd >= 0); + /* If the home dir is already activated, then the UID shift is already applied. */ + if (FLAGS_SET(flags, HOME_SETUP_ALREADY_ACTIVATED)) + return 0; + if (fstat(setup->root_fd, &st) < 0) return log_error_errno(errno, "Failed to stat() home directory: %m"); @@ -820,6 +825,7 @@ int home_maybe_shift_uid( int home_refresh( UserRecord *h, + HomeSetupFlags flags, HomeSetup *setup, UserRecord *header_home, PasswordCache *cache, @@ -840,7 +846,7 @@ int home_refresh( if (r < 0) return r; - r = home_maybe_shift_uid(h, setup); + r = home_maybe_shift_uid(h, flags, setup); if (r < 0) return r; @@ -868,6 +874,7 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) { _cleanup_(home_setup_done) HomeSetup setup = HOME_SETUP_INIT; _cleanup_(user_record_unrefp) UserRecord *new_home = NULL; _cleanup_(password_cache_free) PasswordCache cache = {}; + HomeSetupFlags flags = 0; int r; assert(h); @@ -898,7 +905,7 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) { switch (user_record_storage(h)) { case USER_LUKS: - r = home_activate_luks(h, &setup, &cache, &new_home); + r = home_activate_luks(h, flags, &setup, &cache, &new_home); if (r < 0) return r; @@ -907,14 +914,14 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) { case USER_SUBVOLUME: case USER_DIRECTORY: case USER_FSCRYPT: - r = home_activate_directory(h, &setup, &cache, &new_home); + r = home_activate_directory(h, flags, &setup, &cache, &new_home); if (r < 0) return r; break; case USER_CIFS: - r = home_activate_cifs(h, &setup, &cache, &new_home); + r = home_activate_cifs(h, flags, &setup, &cache, &new_home); if (r < 0) return r; @@ -1602,6 +1609,10 @@ static int home_update(UserRecord *h, UserRecord **ret) { if (r < 0) return r; + r = home_maybe_shift_uid(h, flags, &setup); + if (r < 0) + return r; + r = home_store_header_identity_luks(new_home, &setup, header_home); if (r < 0) return r; @@ -1694,6 +1705,10 @@ static int home_passwd(UserRecord *h, UserRecord **ret_home) { if (r < 0) return r; + r = home_maybe_shift_uid(h, flags, &setup); + if (r < 0) + return r; + switch (user_record_storage(h)) { case USER_LUKS: diff --git a/src/home/homework.h b/src/home/homework.h index 750ad331c8..882a3f500b 100644 --- a/src/home/homework.h +++ b/src/home/homework.h @@ -80,9 +80,9 @@ int keyring_unlink(key_serial_t k); int home_setup(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_header_home); -int home_refresh(UserRecord *h, HomeSetup *setup, UserRecord *header_home, PasswordCache *cache, struct statfs *ret_statfs, UserRecord **ret_new_home); +int home_refresh(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup, UserRecord *header_home, PasswordCache *cache, struct statfs *ret_statfs, UserRecord **ret_new_home); -int home_maybe_shift_uid(UserRecord *h, HomeSetup *setup); +int home_maybe_shift_uid(UserRecord *h, HomeSetupFlags flags, HomeSetup *setup); int home_populate(UserRecord *h, int dir_fd); int home_load_embedded_identity(UserRecord *h, int root_fd, UserRecord *header_home, UserReconcileMode mode, PasswordCache *cache, UserRecord **ret_embedded_home, UserRecord **ret_new_home);