mirror of
https://github.com/systemd/systemd
synced 2026-04-21 14:34:51 +02:00
Compare commits
2 Commits
21838f36a6
...
e99ca14741
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e99ca14741 | ||
|
|
5cf84d2545 |
2
NEWS
2
NEWS
@ -20,7 +20,7 @@ CHANGES WITH 251:
|
|||||||
is mapped almost fully, with the exception of the UID subrange used
|
is mapped almost fully, with the exception of the UID subrange used
|
||||||
for systemd-homed users, with one exception from that: the user's own
|
for systemd-homed users, with one exception from that: the user's own
|
||||||
UID). Unmapped UIDs may not be used for file ownership in the home
|
UID). Unmapped UIDs may not be used for file ownership in the home
|
||||||
dirctory — any chown() attempts with them will fail. With this
|
directory — any chown() attempts with them will fail. With this
|
||||||
release a fourth range is added to these mappings:
|
release a fourth range is added to these mappings:
|
||||||
524288…1879048191. This range is the UID range intended for container
|
524288…1879048191. This range is the UID range intended for container
|
||||||
uses, see:
|
uses, see:
|
||||||
|
|||||||
@ -868,19 +868,36 @@ int getenv_path_list(const char *name, char ***ret_paths) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unsetenv_erase(const char *name) {
|
int getenv_steal_erase(const char *name, char **ret) {
|
||||||
char *p;
|
_cleanup_(erase_and_freep) char *a = NULL;
|
||||||
|
char *e;
|
||||||
|
|
||||||
assert(name);
|
assert(name);
|
||||||
|
|
||||||
p = getenv(name);
|
/* Reads an environment variable, makes a copy of it, erases its memory in the environment block and removes
|
||||||
if (!p)
|
* it from there. Usecase: reading passwords from the env block (which is a bad idea, but useful for
|
||||||
return 0;
|
* testing, and given that people are likely going to misuse this, be thorough) */
|
||||||
|
|
||||||
string_erase(p);
|
e = getenv(name);
|
||||||
|
if (!e) {
|
||||||
|
if (ret)
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
a = strdup(e);
|
||||||
|
if (!a)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
string_erase(e);
|
||||||
|
|
||||||
if (unsetenv(name) < 0)
|
if (unsetenv(name) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
*ret = TAKE_PTR(a);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,3 +70,5 @@ int setenv_systemd_exec_pid(bool update_only);
|
|||||||
int getenv_path_list(const char *name, char ***ret_paths);
|
int getenv_path_list(const char *name, char ***ret_paths);
|
||||||
|
|
||||||
int unsetenv_erase(const char *name);
|
int unsetenv_erase(const char *name);
|
||||||
|
|
||||||
|
int getenv_steal_erase(const char *name, char **ret);
|
||||||
|
|||||||
@ -17,20 +17,13 @@ int enroll_password(
|
|||||||
_cleanup_free_ char *error = NULL;
|
_cleanup_free_ char *error = NULL;
|
||||||
const char *node;
|
const char *node;
|
||||||
int r, keyslot;
|
int r, keyslot;
|
||||||
char *e;
|
|
||||||
|
|
||||||
assert_se(node = crypt_get_device_name(cd));
|
assert_se(node = crypt_get_device_name(cd));
|
||||||
|
|
||||||
e = getenv("NEWPASSWORD");
|
r = getenv_steal_erase("NEWPASSWORD", &new_password);
|
||||||
if (e) {
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to acquire password from environment: %m");
|
||||||
new_password = strdup(e);
|
if (r == 0) {
|
||||||
if (!new_password)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
assert_se(unsetenv_erase("NEWPASSWORD") >= 0);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
_cleanup_free_ char *disk_path = NULL;
|
_cleanup_free_ char *disk_path = NULL;
|
||||||
unsigned i = 5;
|
unsigned i = 5;
|
||||||
const char *id;
|
const char *id;
|
||||||
|
|||||||
@ -409,8 +409,8 @@ static int prepare_luks(
|
|||||||
size_t *ret_volume_key_size) {
|
size_t *ret_volume_key_size) {
|
||||||
|
|
||||||
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
|
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
|
||||||
|
_cleanup_(erase_and_freep) char *envpw = NULL;
|
||||||
_cleanup_(erase_and_freep) void *vk = NULL;
|
_cleanup_(erase_and_freep) void *vk = NULL;
|
||||||
char *e = NULL;
|
|
||||||
size_t vks;
|
size_t vks;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -445,23 +445,17 @@ static int prepare_luks(
|
|||||||
if (!vk)
|
if (!vk)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
e = getenv("PASSWORD");
|
r = getenv_steal_erase("PASSWORD", &envpw);
|
||||||
if (e) {
|
if (r < 0)
|
||||||
_cleanup_(erase_and_freep) char *password = NULL;
|
return log_error_errno(r, "Failed to acquire password from environment: %m");
|
||||||
|
if (r > 0) {
|
||||||
password = strdup(e);
|
|
||||||
if (!password)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
assert_se(unsetenv_erase("PASSWORD") >= 0);
|
|
||||||
|
|
||||||
r = crypt_volume_key_get(
|
r = crypt_volume_key_get(
|
||||||
cd,
|
cd,
|
||||||
CRYPT_ANY_SLOT,
|
CRYPT_ANY_SLOT,
|
||||||
vk,
|
vk,
|
||||||
&vks,
|
&vks,
|
||||||
password,
|
envpw,
|
||||||
strlen(password));
|
strlen(envpw));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Password from environment variable $PASSWORD did not work.");
|
return log_error_errno(r, "Password from environment variable $PASSWORD did not work.");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -30,12 +30,12 @@ int acquire_fido2_key(
|
|||||||
size_t *ret_decrypted_key_size,
|
size_t *ret_decrypted_key_size,
|
||||||
AskPasswordFlags ask_password_flags) {
|
AskPasswordFlags ask_password_flags) {
|
||||||
|
|
||||||
|
_cleanup_(erase_and_freep) char *envpw = NULL;
|
||||||
_cleanup_strv_free_erase_ char **pins = NULL;
|
_cleanup_strv_free_erase_ char **pins = NULL;
|
||||||
_cleanup_free_ void *loaded_salt = NULL;
|
_cleanup_free_ void *loaded_salt = NULL;
|
||||||
bool device_exists = false;
|
bool device_exists = false;
|
||||||
const char *salt;
|
const char *salt;
|
||||||
size_t salt_size;
|
size_t salt_size;
|
||||||
char *e;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
ask_password_flags |= ASK_PASSWORD_PUSH_CACHE | ASK_PASSWORD_ACCEPT_CACHED;
|
ask_password_flags |= ASK_PASSWORD_PUSH_CACHE | ASK_PASSWORD_ACCEPT_CACHED;
|
||||||
@ -66,13 +66,13 @@ int acquire_fido2_key(
|
|||||||
salt = loaded_salt;
|
salt = loaded_salt;
|
||||||
}
|
}
|
||||||
|
|
||||||
e = getenv("PIN");
|
r = getenv_steal_erase("PIN", &envpw);
|
||||||
if (e) {
|
if (r < 0)
|
||||||
pins = strv_new(e);
|
return log_error_errno(r, "Failed to acquire password from environment: %m");
|
||||||
|
if (r > 0) {
|
||||||
|
pins = strv_new(envpw);
|
||||||
if (!pins)
|
if (!pins)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
assert_se(unsetenv_erase("PIN") >= 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|||||||
@ -818,20 +818,19 @@ static bool libcryptsetup_plugins_support(void) {
|
|||||||
|
|
||||||
#if HAVE_LIBCRYPTSETUP_PLUGINS
|
#if HAVE_LIBCRYPTSETUP_PLUGINS
|
||||||
static int acquire_pins_from_env_variable(char ***ret_pins) {
|
static int acquire_pins_from_env_variable(char ***ret_pins) {
|
||||||
char *e;
|
_cleanup_(erase_and_freep) char *envpin = NULL;
|
||||||
_cleanup_strv_free_erase_ char **pins = NULL;
|
_cleanup_strv_free_erase_ char **pins = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(ret_pins);
|
assert(ret_pins);
|
||||||
|
|
||||||
e = getenv("PIN");
|
r = getenv_steal_erase("PIN", &envpin);
|
||||||
if (e) {
|
if (r < 0)
|
||||||
pins = strv_new(e);
|
return log_error_errno(r, "Failed to acquire PIN from environment: %m");
|
||||||
|
if (r > 0) {
|
||||||
|
pins = strv_new(envpin);
|
||||||
if (!pins)
|
if (!pins)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
string_erase(e);
|
|
||||||
if (unsetenv("PIN") < 0)
|
|
||||||
return log_error_errno(errno, "Failed to unset $PIN: %m");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret_pins = TAKE_PTR(pins);
|
*ret_pins = TAKE_PTR(pins);
|
||||||
|
|||||||
@ -201,24 +201,25 @@ static int acquire_existing_password(
|
|||||||
AskPasswordFlags flags) {
|
AskPasswordFlags flags) {
|
||||||
|
|
||||||
_cleanup_(strv_free_erasep) char **password = NULL;
|
_cleanup_(strv_free_erasep) char **password = NULL;
|
||||||
|
_cleanup_(erase_and_freep) char *envpw = NULL;
|
||||||
_cleanup_free_ char *question = NULL;
|
_cleanup_free_ char *question = NULL;
|
||||||
char *e;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(user_name);
|
assert(user_name);
|
||||||
assert(hr);
|
assert(hr);
|
||||||
|
|
||||||
e = getenv("PASSWORD");
|
r = getenv_steal_erase("PASSWORD", &envpw);
|
||||||
if (e) {
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to acquire password from environment: %m");
|
||||||
|
if (r > 0) {
|
||||||
/* People really shouldn't use environment variables for passing passwords. We support this
|
/* People really shouldn't use environment variables for passing passwords. We support this
|
||||||
* only for testing purposes, and do not document the behaviour, so that people won't
|
* only for testing purposes, and do not document the behaviour, so that people won't
|
||||||
* actually use this outside of testing. */
|
* actually use this outside of testing. */
|
||||||
|
|
||||||
r = user_record_set_password(hr, STRV_MAKE(e), true);
|
r = user_record_set_password(hr, STRV_MAKE(envpw), true);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to store password: %m");
|
return log_error_errno(r, "Failed to store password: %m");
|
||||||
|
|
||||||
assert_se(unsetenv_erase("PASSWORD") >= 0);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,24 +262,25 @@ static int acquire_recovery_key(
|
|||||||
AskPasswordFlags flags) {
|
AskPasswordFlags flags) {
|
||||||
|
|
||||||
_cleanup_(strv_free_erasep) char **recovery_key = NULL;
|
_cleanup_(strv_free_erasep) char **recovery_key = NULL;
|
||||||
|
_cleanup_(erase_and_freep) char *envpw = NULL;
|
||||||
_cleanup_free_ char *question = NULL;
|
_cleanup_free_ char *question = NULL;
|
||||||
char *e;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(user_name);
|
assert(user_name);
|
||||||
assert(hr);
|
assert(hr);
|
||||||
|
|
||||||
e = getenv("RECOVERY_KEY");
|
r = getenv_steal_erase("PASSWORD", &envpw);
|
||||||
if (e) {
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to acquire password from environment: %m");
|
||||||
|
if (r > 0) {
|
||||||
/* People really shouldn't use environment variables for passing secrets. We support this
|
/* People really shouldn't use environment variables for passing secrets. We support this
|
||||||
* only for testing purposes, and do not document the behaviour, so that people won't
|
* only for testing purposes, and do not document the behaviour, so that people won't
|
||||||
* actually use this outside of testing. */
|
* actually use this outside of testing. */
|
||||||
|
|
||||||
r = user_record_set_password(hr, STRV_MAKE(e), true); /* recovery keys are stored in the record exactly like regular passwords! */
|
r = user_record_set_password(hr, STRV_MAKE(envpw), true); /* recovery keys are stored in the record exactly like regular passwords! */
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to store recovery key: %m");
|
return log_error_errno(r, "Failed to store recovery key: %m");
|
||||||
|
|
||||||
assert_se(unsetenv_erase("RECOVERY_KEY") >= 0);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,20 +320,21 @@ static int acquire_token_pin(
|
|||||||
AskPasswordFlags flags) {
|
AskPasswordFlags flags) {
|
||||||
|
|
||||||
_cleanup_(strv_free_erasep) char **pin = NULL;
|
_cleanup_(strv_free_erasep) char **pin = NULL;
|
||||||
|
_cleanup_(erase_and_freep) char *envpin = NULL;
|
||||||
_cleanup_free_ char *question = NULL;
|
_cleanup_free_ char *question = NULL;
|
||||||
char *e;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(user_name);
|
assert(user_name);
|
||||||
assert(hr);
|
assert(hr);
|
||||||
|
|
||||||
e = getenv("PIN");
|
r = getenv_steal_erase("PIN", &envpin);
|
||||||
if (e) {
|
if (r < 0)
|
||||||
r = user_record_set_token_pin(hr, STRV_MAKE(e), false);
|
return log_error_errno(r, "Failed to acquire PIN from environment: %m");
|
||||||
|
if (r > 0) {
|
||||||
|
r = user_record_set_token_pin(hr, STRV_MAKE(envpin), false);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to store token PIN: %m");
|
return log_error_errno(r, "Failed to store token PIN: %m");
|
||||||
|
|
||||||
assert_se(unsetenv_erase("PIN") >= 0);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1150,33 +1153,25 @@ static int acquire_new_password(
|
|||||||
bool suggest,
|
bool suggest,
|
||||||
char **ret) {
|
char **ret) {
|
||||||
|
|
||||||
|
_cleanup_(erase_and_freep) char *envpw = NULL;
|
||||||
unsigned i = 5;
|
unsigned i = 5;
|
||||||
char *e;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(user_name);
|
assert(user_name);
|
||||||
assert(hr);
|
assert(hr);
|
||||||
|
|
||||||
e = getenv("NEWPASSWORD");
|
r = getenv_steal_erase("NEWPASSWORD", &envpw);
|
||||||
if (e) {
|
if (r < 0)
|
||||||
_cleanup_(erase_and_freep) char *copy = NULL;
|
return log_error_errno(r, "Failed to acquire password from environment: %m");
|
||||||
|
if (r > 0) {
|
||||||
/* As above, this is not for use, just for testing */
|
/* As above, this is not for use, just for testing */
|
||||||
|
|
||||||
if (ret) {
|
r = user_record_set_password(hr, STRV_MAKE(envpw), /* prepend = */ true);
|
||||||
copy = strdup(e);
|
|
||||||
if (!copy)
|
|
||||||
return log_oom();
|
|
||||||
}
|
|
||||||
|
|
||||||
r = user_record_set_password(hr, STRV_MAKE(e), /* prepend = */ true);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to store password: %m");
|
return log_error_errno(r, "Failed to store password: %m");
|
||||||
|
|
||||||
assert_se(unsetenv_erase("NEWPASSWORD") >= 0);
|
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = TAKE_PTR(copy);
|
*ret = TAKE_PTR(envpw);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -275,15 +275,17 @@ int pkcs11_token_login(
|
|||||||
|
|
||||||
for (unsigned tries = 0; tries < 3; tries++) {
|
for (unsigned tries = 0; tries < 3; tries++) {
|
||||||
_cleanup_strv_free_erase_ char **passwords = NULL;
|
_cleanup_strv_free_erase_ char **passwords = NULL;
|
||||||
char **i, *e;
|
_cleanup_(erase_and_freep) char *envpin = NULL;
|
||||||
|
char **i;
|
||||||
|
|
||||||
e = getenv("PIN");
|
r = getenv_steal_erase("PIN", &envpin);
|
||||||
if (e) {
|
if (r < 0)
|
||||||
passwords = strv_new(e);
|
return log_error_errno(r, "Failed to acquire PIN from environment: %m");
|
||||||
|
if (r > 0) {
|
||||||
|
passwords = strv_new(envpin);
|
||||||
if (!passwords)
|
if (!passwords)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
assert_se(unsetenv_erase("PIN") >= 0);
|
|
||||||
} else if (headless)
|
} else if (headless)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the 'PIN' environment variable.");
|
return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the 'PIN' environment variable.");
|
||||||
else {
|
else {
|
||||||
|
|||||||
@ -406,17 +406,17 @@ TEST(setenv_systemd_exec_pid) {
|
|||||||
assert_se(set_unset_env("SYSTEMD_EXEC_PID", saved, 1) >= 0);
|
assert_se(set_unset_env("SYSTEMD_EXEC_PID", saved, 1) >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(unsetenv_erase) {
|
TEST(getenv_steal_erase) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = safe_fork("(sd-unsetenverase)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
r = safe_fork("(sd-getenvstealerase)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
_cleanup_strv_free_ char **l = NULL;
|
_cleanup_strv_free_ char **l = NULL;
|
||||||
char **e;
|
char **e;
|
||||||
|
|
||||||
/* child */
|
/* child */
|
||||||
|
|
||||||
assert_se(unsetenv_erase("thisenvvardefinitelywontexist") == 0);
|
assert_se(getenv_steal_erase("thisenvvardefinitelywontexist", NULL) == 0);
|
||||||
|
|
||||||
l = strv_new("FOO=BAR", "QUUX=PIFF", "ONE=TWO", "A=B");
|
l = strv_new("FOO=BAR", "QUUX=PIFF", "ONE=TWO", "A=B");
|
||||||
assert_se(strv_length(l) == 4);
|
assert_se(strv_length(l) == 4);
|
||||||
@ -424,7 +424,7 @@ TEST(unsetenv_erase) {
|
|||||||
environ = l;
|
environ = l;
|
||||||
|
|
||||||
STRV_FOREACH(e, environ) {
|
STRV_FOREACH(e, environ) {
|
||||||
_cleanup_free_ char *n = NULL;
|
_cleanup_free_ char *n = NULL, *copy1 = NULL, *copy2 = NULL;
|
||||||
char *eq;
|
char *eq;
|
||||||
|
|
||||||
eq = strchr(*e, '=');
|
eq = strchr(*e, '=');
|
||||||
@ -434,9 +434,13 @@ TEST(unsetenv_erase) {
|
|||||||
n = strndup(*e, eq - *e);
|
n = strndup(*e, eq - *e);
|
||||||
assert_se(n);
|
assert_se(n);
|
||||||
|
|
||||||
assert_se(streq_ptr(getenv(n), eq + 1));
|
copy1 = strdup(eq + 1);
|
||||||
|
assert_se(copy1);
|
||||||
|
|
||||||
|
assert_se(streq_ptr(getenv(n), copy1));
|
||||||
assert_se(getenv(n) == eq + 1);
|
assert_se(getenv(n) == eq + 1);
|
||||||
assert_se(unsetenv_erase(n) > 0);
|
assert_se(getenv_steal_erase(n, ©2) > 0);
|
||||||
|
assert_se(streq_ptr(copy1, copy2));
|
||||||
assert_se(isempty(eq + 1));
|
assert_se(isempty(eq + 1));
|
||||||
assert_se(!getenv(n));
|
assert_se(!getenv(n));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user