mirror of
https://github.com/systemd/systemd
synced 2026-03-17 18:44:46 +01:00
Compare commits
6 Commits
33f2de7b64
...
2cbca51a71
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cbca51a71 | ||
|
|
3745355764 | ||
|
|
ba405b2200 | ||
|
|
bd6d28f21a | ||
|
|
1e472a6ce4 | ||
|
|
16eff8271b |
5
TODO
5
TODO
@ -711,9 +711,6 @@ Features:
|
|||||||
* add proper dbus APIs for the various sd_notify() commands, such as MAINPID=1
|
* add proper dbus APIs for the various sd_notify() commands, such as MAINPID=1
|
||||||
and so on, which would mean we could report errors and such.
|
and so on, which would mean we could report errors and such.
|
||||||
|
|
||||||
* teach tmpfiles.d q/Q logic something sensible in the context of XFS/ext4
|
|
||||||
project quota
|
|
||||||
|
|
||||||
* introduce DefaultSlice= or so in system.conf that allows changing where we
|
* introduce DefaultSlice= or so in system.conf that allows changing where we
|
||||||
place our units by default, i.e. change system.slice to something
|
place our units by default, i.e. change system.slice to something
|
||||||
else. Similar, ManagerSlice= should exist so that PID1's own scope unit could
|
else. Similar, ManagerSlice= should exist so that PID1's own scope unit could
|
||||||
@ -1335,6 +1332,8 @@ Features:
|
|||||||
should not follow symlinks. None of the other adjustment or creation
|
should not follow symlinks. None of the other adjustment or creation
|
||||||
calls follow symlinks.
|
calls follow symlinks.
|
||||||
- add --test mode
|
- add --test mode
|
||||||
|
- teach tmpfiles.d q/Q logic something sensible in the context of XFS/ext4
|
||||||
|
project quota
|
||||||
|
|
||||||
* make sure systemd-ask-password-wall does not shutdown systemd-ask-password-console too early
|
* make sure systemd-ask-password-wall does not shutdown systemd-ask-password-console too early
|
||||||
|
|
||||||
|
|||||||
@ -529,11 +529,19 @@
|
|||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>silent</option></term>
|
<term><option>password-echo=yes|no|masked</option></term>
|
||||||
|
|
||||||
<listitem><para>If an encryption password or security token PIN is
|
<listitem><para>Controls whether to echo passwords or security token PINs
|
||||||
read from console, no asterisks will be shown while typing the pin or
|
that are read from console. Takes a boolean or the special string <literal>masked</literal>.
|
||||||
password.</para></listitem>
|
The default is <option>password-echo=masked</option>.</para>
|
||||||
|
|
||||||
|
<para>If enabled, the typed characters are echoed literally. If disabled,
|
||||||
|
the typed characters are not echoed in any form, the user will not get
|
||||||
|
feedback on their input. If set to <literal>masked</literal>, an asterisk
|
||||||
|
(<literal>*</literal>) is echoed for each character typed. Regardless of
|
||||||
|
which mode is chosen, if the user hits the tabulator key (<literal>↹</literal>)
|
||||||
|
at any time, or the backspace key (<literal>⌫</literal>) before any other
|
||||||
|
data has been entered, then echo is turned off.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|||||||
@ -71,3 +71,22 @@ int glob_extend(char ***strv, const char *path, int flags) {
|
|||||||
|
|
||||||
return strv_extend_strv(strv, g.gl_pathv, false);
|
return strv_extend_strv(strv, g.gl_pathv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int glob_non_glob_prefix(const char *path, char **ret) {
|
||||||
|
/* Return the path of the path that has no glob characters. */
|
||||||
|
|
||||||
|
size_t n = strcspn(path, GLOB_CHARS);
|
||||||
|
|
||||||
|
if (path[n] != '\0')
|
||||||
|
while (n > 0 && path[n-1] != '/')
|
||||||
|
n--;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
char *ans = strndup(path, n);
|
||||||
|
if (!ans)
|
||||||
|
return -ENOMEM;
|
||||||
|
*ret = ans;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -13,6 +13,8 @@ int safe_glob(const char *path, int flags, glob_t *pglob);
|
|||||||
int glob_exists(const char *path);
|
int glob_exists(const char *path);
|
||||||
int glob_extend(char ***strv, const char *path, int flags);
|
int glob_extend(char ***strv, const char *path, int flags);
|
||||||
|
|
||||||
|
int glob_non_glob_prefix(const char *path, char **ret);
|
||||||
|
|
||||||
#define _cleanup_globfree_ _cleanup_(globfree)
|
#define _cleanup_globfree_ _cleanup_(globfree)
|
||||||
|
|
||||||
_pure_ static inline bool string_is_glob(const char *p) {
|
_pure_ static inline bool string_is_glob(const char *p) {
|
||||||
|
|||||||
@ -27,9 +27,8 @@ int acquire_fido2_key(
|
|||||||
Fido2EnrollFlags required,
|
Fido2EnrollFlags required,
|
||||||
void **ret_decrypted_key,
|
void **ret_decrypted_key,
|
||||||
size_t *ret_decrypted_key_size,
|
size_t *ret_decrypted_key_size,
|
||||||
bool silent) {
|
AskPasswordFlags ask_password_flags) {
|
||||||
|
|
||||||
AskPasswordFlags flags = ASK_PASSWORD_PUSH_CACHE | ASK_PASSWORD_ACCEPT_CACHED | (silent*ASK_PASSWORD_SILENT);
|
|
||||||
_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;
|
||||||
const char *salt;
|
const char *salt;
|
||||||
@ -37,6 +36,8 @@ int acquire_fido2_key(
|
|||||||
char *e;
|
char *e;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
ask_password_flags |= ASK_PASSWORD_PUSH_CACHE | ASK_PASSWORD_ACCEPT_CACHED;
|
||||||
|
|
||||||
assert(cid);
|
assert(cid);
|
||||||
assert(key_file || key_data);
|
assert(key_file || key_data);
|
||||||
|
|
||||||
@ -96,11 +97,11 @@ int acquire_fido2_key(
|
|||||||
if (headless)
|
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.");
|
||||||
|
|
||||||
r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, flags, &pins);
|
r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, ask_password_flags, &pins);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to ask for user password: %m");
|
return log_error_errno(r, "Failed to ask for user password: %m");
|
||||||
|
|
||||||
flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
|
ask_password_flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ int acquire_fido2_key(
|
|||||||
Fido2EnrollFlags required,
|
Fido2EnrollFlags required,
|
||||||
void **ret_decrypted_key,
|
void **ret_decrypted_key,
|
||||||
size_t *ret_decrypted_key_size,
|
size_t *ret_decrypted_key_size,
|
||||||
bool silent);
|
AskPasswordFlags ask_password_flags);
|
||||||
|
|
||||||
int find_fido2_auto_data(
|
int find_fido2_auto_data(
|
||||||
struct crypt_device *cd,
|
struct crypt_device *cd,
|
||||||
@ -58,7 +58,7 @@ static inline int acquire_fido2_key(
|
|||||||
Fido2EnrollFlags required,
|
Fido2EnrollFlags required,
|
||||||
void **ret_decrypted_key,
|
void **ret_decrypted_key,
|
||||||
size_t *ret_decrypted_key_size,
|
size_t *ret_decrypted_key_size,
|
||||||
bool silent) {
|
AskPasswordFlags ask_password_flags) {
|
||||||
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||||
"FIDO2 token support not available.");
|
"FIDO2 token support not available.");
|
||||||
|
|||||||
@ -58,7 +58,7 @@ static char *arg_header = NULL;
|
|||||||
static unsigned arg_tries = 3;
|
static unsigned arg_tries = 3;
|
||||||
static bool arg_readonly = false;
|
static bool arg_readonly = false;
|
||||||
static bool arg_verify = false;
|
static bool arg_verify = false;
|
||||||
static bool arg_silent = false;
|
static AskPasswordFlags arg_ask_password_flags = 0;
|
||||||
static bool arg_discards = false;
|
static bool arg_discards = false;
|
||||||
static bool arg_same_cpu_crypt = false;
|
static bool arg_same_cpu_crypt = false;
|
||||||
static bool arg_submit_from_crypt_cpus = false;
|
static bool arg_submit_from_crypt_cpus = false;
|
||||||
@ -235,9 +235,20 @@ static int parse_one_option(const char *option) {
|
|||||||
arg_readonly = true;
|
arg_readonly = true;
|
||||||
else if (streq(option, "verify"))
|
else if (streq(option, "verify"))
|
||||||
arg_verify = true;
|
arg_verify = true;
|
||||||
else if (streq(option, "silent"))
|
else if ((val = startswith(option, "password-echo="))) {
|
||||||
arg_silent = true;
|
if (streq(val, "masked"))
|
||||||
else if (STR_IN_SET(option, "allow-discards", "discard"))
|
arg_ask_password_flags &= ~(ASK_PASSWORD_ECHO|ASK_PASSWORD_SILENT);
|
||||||
|
else {
|
||||||
|
r = parse_boolean(val);
|
||||||
|
if (r < 0) {
|
||||||
|
log_warning_errno(r, "Invalid password-echo= option \"%s\", ignoring.", val);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_ECHO, r);
|
||||||
|
SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_SILENT, !r);
|
||||||
|
}
|
||||||
|
} else if (STR_IN_SET(option, "allow-discards", "discard"))
|
||||||
arg_discards = true;
|
arg_discards = true;
|
||||||
else if (streq(option, "same-cpu-crypt"))
|
else if (streq(option, "same-cpu-crypt"))
|
||||||
arg_same_cpu_crypt = true;
|
arg_same_cpu_crypt = true;
|
||||||
@ -543,7 +554,7 @@ static int get_password(
|
|||||||
_cleanup_strv_free_erase_ char **passwords = NULL;
|
_cleanup_strv_free_erase_ char **passwords = NULL;
|
||||||
char **p, *id;
|
char **p, *id;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
AskPasswordFlags flags = ASK_PASSWORD_PUSH_CACHE | (arg_silent*ASK_PASSWORD_SILENT);
|
AskPasswordFlags flags = arg_ask_password_flags | ASK_PASSWORD_PUSH_CACHE;
|
||||||
|
|
||||||
assert(vol);
|
assert(vol);
|
||||||
assert(src);
|
assert(src);
|
||||||
@ -811,7 +822,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
|
|||||||
arg_headless,
|
arg_headless,
|
||||||
required,
|
required,
|
||||||
&decrypted_key, &decrypted_key_size,
|
&decrypted_key, &decrypted_key_size,
|
||||||
arg_silent);
|
arg_ask_password_flags);
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
break;
|
break;
|
||||||
if (r != -EAGAIN) /* EAGAIN means: token not found */
|
if (r != -EAGAIN) /* EAGAIN means: token not found */
|
||||||
|
|||||||
@ -13,6 +13,8 @@
|
|||||||
#include "tmpfile-util.h"
|
#include "tmpfile-util.h"
|
||||||
|
|
||||||
static void test_glob_exists(void) {
|
static void test_glob_exists(void) {
|
||||||
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
char name[] = "/tmp/test-glob_exists.XXXXXX";
|
char name[] = "/tmp/test-glob_exists.XXXXXX";
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int r;
|
int r;
|
||||||
@ -48,6 +50,8 @@ static void test_glob_no_dot(void) {
|
|||||||
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
assert_se(mkdtemp(template));
|
assert_se(mkdtemp(template));
|
||||||
|
|
||||||
fn = strjoina(template, "/*");
|
fn = strjoina(template, "/*");
|
||||||
@ -68,6 +72,8 @@ static void test_safe_glob(void) {
|
|||||||
_cleanup_globfree_ glob_t g = {};
|
_cleanup_globfree_ glob_t g = {};
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
assert_se(mkdtemp(template));
|
assert_se(mkdtemp(template));
|
||||||
|
|
||||||
fn = strjoina(template, "/*");
|
fn = strjoina(template, "/*");
|
||||||
@ -93,10 +99,32 @@ static void test_safe_glob(void) {
|
|||||||
(void) rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL);
|
(void) rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_glob_non_glob_prefix_one(const char *path, const char *expected) {
|
||||||
|
_cleanup_free_ char *t;
|
||||||
|
|
||||||
|
assert_se(glob_non_glob_prefix(path, &t) == 0);
|
||||||
|
assert_se(streq(t, expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_glob_non_glob(void) {
|
||||||
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
|
test_glob_non_glob_prefix_one("/tmp/.X11-*", "/tmp/");
|
||||||
|
test_glob_non_glob_prefix_one("/tmp/*", "/tmp/");
|
||||||
|
test_glob_non_glob_prefix_one("/tmp*", "/");
|
||||||
|
test_glob_non_glob_prefix_one("/tmp/*/whatever", "/tmp/");
|
||||||
|
test_glob_non_glob_prefix_one("/tmp/*/whatever?", "/tmp/");
|
||||||
|
test_glob_non_glob_prefix_one("/?", "/");
|
||||||
|
|
||||||
|
char *x;
|
||||||
|
assert_se(glob_non_glob_prefix("?", &x) == -ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
test_glob_exists();
|
test_glob_exists();
|
||||||
test_glob_no_dot();
|
test_glob_no_dot();
|
||||||
test_safe_glob();
|
test_safe_glob();
|
||||||
|
test_glob_non_glob();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2344,6 +2344,8 @@ static int clean_item(Item *i) {
|
|||||||
|
|
||||||
static int process_item(Item *i, OperationMask operation) {
|
static int process_item(Item *i, OperationMask operation) {
|
||||||
OperationMask todo;
|
OperationMask todo;
|
||||||
|
_cleanup_free_ char *_path = NULL;
|
||||||
|
const char *path;
|
||||||
int r, q, p;
|
int r, q, p;
|
||||||
|
|
||||||
assert(i);
|
assert(i);
|
||||||
@ -2354,9 +2356,21 @@ static int process_item(Item *i, OperationMask operation) {
|
|||||||
|
|
||||||
i->done |= operation;
|
i->done |= operation;
|
||||||
|
|
||||||
r = chase_symlinks(i->path, arg_root, CHASE_NO_AUTOFS|CHASE_WARN, NULL, NULL);
|
path = i->path;
|
||||||
|
if (string_is_glob(path)) {
|
||||||
|
/* We can't easily check whether a glob matches any autofs path, so let's do the check only
|
||||||
|
* for the non-glob part. */
|
||||||
|
|
||||||
|
r = glob_non_glob_prefix(path, &_path);
|
||||||
|
if (r < 0 && r != -ENOENT)
|
||||||
|
return log_debug_errno(r, "Failed to deglob path: %m");
|
||||||
|
if (r >= 0)
|
||||||
|
path = _path;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = chase_symlinks(path, arg_root, CHASE_NO_AUTOFS|CHASE_NONEXISTENT|CHASE_WARN, NULL, NULL);
|
||||||
if (r == -EREMOTE) {
|
if (r == -EREMOTE) {
|
||||||
log_notice_errno(r, "Skipping %s", i->path);
|
log_notice_errno(r, "Skipping %s", i->path); /* We log the configured path, to not confuse the user. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user