if (arg_root_password)
return 0;
- r = read_credential("passwd.hashed-password.root", (void**) &arg_root_password, NULL);
- if (r == -ENOENT) {
- r = read_credential("passwd.plaintext-password.root", (void**) &arg_root_password, NULL);
- if (r < 0)
- log_debug_errno(r, "Couldn't read credential 'passwd.{hashed|plaintext}-password.root', ignoring: %m");
- else {
- arg_root_password_is_hashed = false;
- return 0;
- }
- } else if (r < 0)
- log_debug_errno(r, "Couldn't read credential 'passwd.hashed-password.root', ignoring: %m");
- else {
- arg_root_password_is_hashed = true;
+ if (get_credential_user_password("root", &arg_root_password, &arg_root_password_is_hashed) >= 0)
return 0;
- }
if (!arg_prompt_root_password)
return 0;
(char**) ret, ret_size);
}
+int get_credential_user_password(const char *username, char **ret_password, bool *ret_is_hashed) {
+ _cleanup_(erase_and_freep) char *creds_password = NULL;
+ _cleanup_free_ char *cn = NULL;
+ int r;
+
+ /* Try to pick up the password for this account via the credentials logic */
+ cn = strjoin("passwd.hashed-password.", username);
+ if (!cn)
+ return -ENOMEM;
+
+ r = read_credential(cn, (void**) &creds_password, NULL);
+ if (r == -ENOENT) {
+ free(cn);
+ cn = strjoin("passwd.plaintext-password.", username);
+ if (!cn)
+ return -ENOMEM;
+
+ r = read_credential(cn, (void**) &creds_password, NULL);
+ if (r < 0)
+ log_debug_errno(r, "Couldn't read credential '%s', ignoring: %m", cn);
+ else
+ *ret_is_hashed = false;
+ } else if (r < 0)
+ log_debug_errno(r, "Couldn't read credential '%s', ignoring: %m", cn);
+ else
+ *ret_is_hashed = true;
+
+ *ret_password = TAKE_PTR(creds_password);
+
+ return r;
+}
+
#if HAVE_OPENSSL
#define CREDENTIAL_HOST_SECRET_SIZE 4096
int get_credential_host_secret(CredentialSecretFlags flags, void **ret, size_t *ret_size);
+int get_credential_user_password(const char *username, char **ret_password, bool *ret_is_hashed);
+
/* The four modes we support: keyed only by on-disk key, only by TPM2 HMAC key, and by the combination of
* both, as well as one with a fixed zero length key if TPM2 is missing (the latter of course provides no
* authenticity or confidentiality, but is still useful for integrity protection, and makes things simpler
ORDERED_HASHMAP_FOREACH(i, todo_uids) {
_cleanup_(erase_and_freep) char *creds_password = NULL;
- _cleanup_free_ char *cn = NULL;
+ bool is_hashed;
struct spwd n = {
.sp_namp = i->name,
.sp_flag = ULONG_MAX, /* this appears to be what everybody does ... */
};
- /* Try to pick up the password for this account via the credentials logic */
- cn = strjoin("passwd.hashed-password.", i->name);
- if (!cn)
- return -ENOMEM;
-
- r = read_credential(cn, (void**) &creds_password, NULL);
- if (r == -ENOENT) {
- _cleanup_(erase_and_freep) char *plaintext_password = NULL;
-
- free(cn);
- cn = strjoin("passwd.plaintext-password.", i->name);
- if (!cn)
- return -ENOMEM;
+ r = get_credential_user_password(i->name, &creds_password, &is_hashed);
+ if (r < 0)
+ log_debug_errno(r, "Couldn't read password credential for user '%s', ignoring: %m", i->name);
- r = read_credential(cn, (void**) &plaintext_password, NULL);
+ if (creds_password && !is_hashed) {
+ _cleanup_(erase_and_freep) char* plaintext_password = TAKE_PTR(creds_password);
+ r = hash_password(plaintext_password, &creds_password);
if (r < 0)
- log_debug_errno(r, "Couldn't read credential '%s', ignoring: %m", cn);
- else {
- r = hash_password(plaintext_password, &creds_password);
- if (r < 0)
- return log_debug_errno(r, "Failed to hash password: %m");
- }
- } else if (r < 0)
- log_debug_errno(r, "Couldn't read credential '%s', ignoring: %m", cn);
+ return log_debug_errno(r, "Failed to hash password: %m");
+ }
if (creds_password)
n.sp_pwdp = creds_password;