diff --git a/src/cryptenroll/cryptenroll.c b/src/cryptenroll/cryptenroll.c index cf99aab96db..c9bc9a24891 100644 --- a/src/cryptenroll/cryptenroll.c +++ b/src/cryptenroll/cryptenroll.c @@ -381,6 +381,28 @@ static int parse_argv(int argc, char *argv[]) { return 1; } +static int check_for_homed(struct crypt_device *cd) { + int r; + + assert_se(cd); + + /* Politely refuse operating on homed volumes. The enrolled tokens for the user record and the LUKS2 + * volume should not get out of sync. */ + + for (int token = 0; token < crypt_token_max(CRYPT_LUKS2); token ++) { + r = cryptsetup_get_token_as_json(cd, token, "systemd-homed", NULL); + if (IN_SET(r, -ENOENT, -EINVAL, -EMEDIUMTYPE)) + continue; + if (r < 0) + return log_error_errno(r, "Failed to read JSON token data off disk: %m"); + + return log_error_errno(SYNTHETIC_ERRNO(EHOSTDOWN), + "LUKS2 volume is managed by systemd-homed, please use homectl to enroll tokens."); + } + + return 0; +} + static int prepare_luks( struct crypt_device **ret_cd, void **ret_volume_key, @@ -405,6 +427,10 @@ static int prepare_luks( if (r < 0) return log_error_errno(r, "Failed to load LUKS2 superblock: %m"); + r = check_for_homed(cd); + if (r < 0) + return r; + if (!ret_volume_key) { *ret_cd = TAKE_PTR(cd); return 0;