mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-06 13:17:44 +03:00
Merge pull request #24273 from lnussel/refactor_sysuser_creds
Refactor sysuser creds
This commit is contained in:
commit
c94887f10d
@ -266,7 +266,8 @@ services where they are ultimately consumed.
|
||||
three of these specific switches would set credential `foo` to `bar`.)
|
||||
Passing credentials via the SMBIOS mechanism is typically preferable over
|
||||
`fw_cfg` since it is faster and less specific to the chosen VMM
|
||||
implementation.
|
||||
implementation. Moreover, `fw_cfg` has a 55 character limitation
|
||||
on names passed that way. So some settings may not fit.
|
||||
|
||||
3. Credentials can also be passed into a system via the kernel command line,
|
||||
via the `systemd.set-credential=` kernel command line option. Note though
|
||||
|
@ -595,21 +595,8 @@ static int prompt_root_password(void) {
|
||||
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;
|
||||
|
@ -83,6 +83,38 @@ int read_credential(const char *name, void **ret, size_t *ret_size) {
|
||||
(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
|
||||
|
@ -44,6 +44,8 @@ typedef enum CredentialSecretFlags {
|
||||
|
||||
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
|
||||
|
@ -581,7 +581,7 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
|
||||
|
||||
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,
|
||||
@ -595,30 +595,16 @@ static int write_temporary_shadow(const char *shadow_path, FILE **tmpfile, char
|
||||
.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 = 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**) &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 = 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;
|
||||
|
Loading…
Reference in New Issue
Block a user