Compare commits

...

11 Commits

Author SHA1 Message Date
Yu Watanabe 2b6a90d17f selinux: update log message to suppress warning by coverity
Fixes CID#1417440 and CID#1417438.
2020-02-06 16:04:50 +01:00
Yu Watanabe 9207625d9b
Merge pull request #14800 from keszybz/ask-password-echo
ask-password: give a hint to cancel echo
2020-02-06 23:49:54 +09:00
Yu Watanabe db99904bc8 sysctl: fix segfault
Fixes #14801.
2020-02-06 23:49:32 +09:00
Zbigniew Jędrzejewski-Szmek 8aaf18e08a shared/ask-password-api: show "(press TAB for no echo)"
For #8495: it is arguably useful to not show the length of the password
in public spaces. It is possible to press TAB or BS to cancel the asterisks,
but this is not very discoverable. Let's make it discoverable by showing
a message (in gray). The message is "erased" after the first character
is entered.
2020-02-06 10:51:24 +01:00
Zbigniew Jędrzejewski-Szmek 72c08a471c shared/ask-password-api: return "error" when dialogue is cancelled
test-ask-password-api would crash if ^D was pressed.
If think the callers generally expect a non-empty strv as reply. Let's
return an error if we have nothing to return.

Also modernize test-ask-password-api a bit.
2020-02-06 10:51:13 +01:00
Zbigniew Jędrzejewski-Szmek 5650ec7a11
Merge pull request #14156 from fbuihuu/deal-with-aliases-when-disabling
Consider aliases in /usr when disabling units
2020-02-06 10:46:21 +01:00
Christian Göttsche 1acf344dfa core: do not prepare a SELinux context for dummy files for devicenode bind-mounting
Let systemd create the dummy file where a device node will be mounted on with the default label for the parent directory (e.g. /tmp/namespace-dev-yTMwAe/dev/).

Fixes: #13762
2020-02-06 10:20:14 +01:00
Zbigniew Jędrzejewski-Szmek 39e96f844a firstboot: add missing check
If we check length of 'a', we must do the same for 'b'.
2020-02-06 09:52:39 +01:00
Franck Bui 972f3176fa shared/install: drop an unused variable in config_parse_also() 2020-01-10 14:28:52 +01:00
Franck Bui 66a19d85a5 shared/install: try harder to find enablement symlinks when disabling a unit
It might be needed to follow symlinks more deeply when we're looking for
enablement symlinks pointing to the removed service.

Let's consider the case where service 'old' is being renamed 'new' (will happen
most likely during package upgrade). Before the service is going to be renamed,
there's the following enablement symlink:

 /etc/systemd/system/multi-user.target.wants/old.service -> /usr/lib/systemd/system/old.service

In order to rename 'old' into 'new' and transparently restart the service, the
old name is still provided as a 'static' alias for the new service. This should
also help keeping backward compatibilities since the old name might still be
embedded in unit files, scripts, generators and such.

Hence after the package is upgraded, the following symlinks including the
enablement symlink are present:

 /usr/lib/systemd/system/old.service -> new.service
 /etc/systemd/system/multi-user.target.wants/old.service -> /usr/lib/systemd/system/old.service

If later the user decides to disable the service, we should figure out that the
enablement symlink (which still has the old name) is actually referring to 'new'
(indirectly) even if it points to the alias.
2020-01-10 14:28:42 +01:00
Franck Bui 29a743f993 core: explicit mention of unit ID is redundant with log_unit_*() 2020-01-10 14:20:28 +01:00
8 changed files with 56 additions and 32 deletions

View File

@ -629,10 +629,9 @@ static int clone_device_node(
} }
/* We're about to fallback to bind-mounting the device /* We're about to fallback to bind-mounting the device
* node. So create a dummy bind-mount target. */ * node. So create a dummy bind-mount target.
mac_selinux_create_file_prepare(d, 0); * Do not prepare device-node SELinux label (see issue 13762) */
r = mknod(dn, S_IFREG, 0); r = mknod(dn, S_IFREG, 0);
mac_selinux_create_file_clear();
if (r < 0 && errno != EEXIST) if (r < 0 && errno != EEXIST)
return log_debug_errno(errno, "mknod() fallback failed for '%s': %m", d); return log_debug_errno(errno, "mknod() fallback failed for '%s': %m", d);

View File

@ -223,7 +223,7 @@ int mac_selinux_generic_access_check(
r = getfilecon_raw(path, &fcon); r = getfilecon_raw(path, &fcon);
if (r < 0) { if (r < 0) {
log_warning_errno(errno, "SELinux getfilecon_raw on '%s' failed: %m (tclass=%s perm=%s)", path, tclass, permission); log_warning_errno(errno, "SELinux getfilecon_raw on '%s' failed (tclass=%s perm=%s): %m", path, tclass, permission);
r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get file context on %s.", path); r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get file context on %s.", path);
goto finish; goto finish;
} }
@ -232,7 +232,7 @@ int mac_selinux_generic_access_check(
} else { } else {
r = getcon_raw(&fcon); r = getcon_raw(&fcon);
if (r < 0) { if (r < 0) {
log_warning_errno(errno, "SELinux getcon_raw failed: %m (tclass=%s perm=%s)", tclass, permission); log_warning_errno(errno, "SELinux getcon_raw failed (tclass=%s perm=%s): %m", tclass, permission);
r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context."); r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context.");
goto finish; goto finish;
} }

View File

@ -5388,7 +5388,7 @@ static void unit_update_dependency_mask(Unit *u, UnitDependency d, Unit *other,
if (di.origin_mask == 0 && di.destination_mask == 0) { if (di.origin_mask == 0 && di.destination_mask == 0) {
/* No bit set anymore, let's drop the whole entry */ /* No bit set anymore, let's drop the whole entry */
assert_se(hashmap_remove(u->dependencies[d], other)); assert_se(hashmap_remove(u->dependencies[d], other));
log_unit_debug(u, "%s lost dependency %s=%s", u->id, unit_dependency_to_string(d), other->id); log_unit_debug(u, "lost dependency %s=%s", unit_dependency_to_string(d), other->id);
} else } else
/* Mask was reduced, let's update the entry */ /* Mask was reduced, let's update the entry */
assert_se(hashmap_update(u->dependencies[d], other, di.data) == 0); assert_se(hashmap_update(u->dependencies[d], other, di.data) == 0);

View File

@ -550,10 +550,9 @@ static int prompt_root_password(void) {
r = ask_password_tty(-1, msg1, NULL, 0, 0, NULL, &a); r = ask_password_tty(-1, msg1, NULL, 0, 0, NULL, &a);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to query root password: %m"); return log_error_errno(r, "Failed to query root password: %m");
if (strv_length(a) != 1) { if (strv_length(a) != 1)
log_warning("Received multiple passwords, where we expected one."); return log_error_errno(SYNTHETIC_ERRNO(EIO),
return -EINVAL; "Received multiple passwords, where we expected one.");
}
if (isempty(*a)) { if (isempty(*a)) {
log_warning("No password entered, skipping."); log_warning("No password entered, skipping.");
@ -563,6 +562,9 @@ static int prompt_root_password(void) {
r = ask_password_tty(-1, msg2, NULL, 0, 0, NULL, &b); r = ask_password_tty(-1, msg2, NULL, 0, 0, NULL, &b);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to query root password: %m"); return log_error_errno(r, "Failed to query root password: %m");
if (strv_length(b) != 1)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
"Received multiple passwords, where we expected one.");
if (!streq(*a, *b)) { if (!streq(*a, *b)) {
log_error("Entered passwords did not match, please try again."); log_error("Entered passwords did not match, please try again.");

View File

@ -394,6 +394,10 @@ finish:
return r; return r;
} }
#define NO_ECHO "(no echo) "
#define PRESS_TAB "(press TAB for no echo) "
#define SKIPPED "(skipped)"
int ask_password_tty( int ask_password_tty(
int ttyfd, int ttyfd,
const char *message, const char *message,
@ -409,7 +413,7 @@ int ask_password_tty(
_POLL_MAX, _POLL_MAX,
}; };
bool reset_tty = false, dirty = false, use_color = false; bool reset_tty = false, dirty = false, use_color = false, press_tab_visible = false;
_cleanup_close_ int cttyfd = -1, notify = -1; _cleanup_close_ int cttyfd = -1, notify = -1;
struct termios old_termios, new_termios; struct termios old_termios, new_termios;
char passphrase[LINE_MAX + 1] = {}, *x; char passphrase[LINE_MAX + 1] = {}, *x;
@ -465,6 +469,13 @@ int ask_password_tty(
(void) loop_write(ttyfd, message, strlen(message), false); (void) loop_write(ttyfd, message, strlen(message), false);
(void) loop_write(ttyfd, " ", 1, false); (void) loop_write(ttyfd, " ", 1, false);
if (!(flags & ASK_PASSWORD_SILENT)) {
if (use_color)
(void) loop_write(ttyfd, ANSI_GREY, STRLEN(ANSI_GREY), false);
(void) loop_write(ttyfd, PRESS_TAB, strlen(PRESS_TAB), false);
press_tab_visible = true;
}
if (use_color) if (use_color)
(void) loop_write(ttyfd, ANSI_NORMAL, STRLEN(ANSI_NORMAL), false); (void) loop_write(ttyfd, ANSI_NORMAL, STRLEN(ANSI_NORMAL), false);
@ -550,13 +561,19 @@ int ask_password_tty(
} }
if (press_tab_visible) {
assert(ttyfd >= 0);
backspace_chars(ttyfd, strlen(PRESS_TAB));
press_tab_visible = false;
}
/* We treat EOF, newline and NUL byte all as valid end markers */ /* We treat EOF, newline and NUL byte all as valid end markers */
if (n == 0 || c == '\n' || c == 0) if (n == 0 || c == '\n' || c == 0)
break; break;
if (c == 4) { /* C-d also known as EOT */ if (c == 4) { /* C-d also known as EOT */
if (ttyfd >= 0) if (ttyfd >= 0)
(void) loop_write(ttyfd, "(skipped)", 9, false); (void) loop_write(ttyfd, SKIPPED, strlen(SKIPPED), false);
goto skipped; goto skipped;
} }
@ -606,7 +623,7 @@ int ask_password_tty(
* first key (and only as first key), or ... */ * first key (and only as first key), or ... */
if (ttyfd >= 0) if (ttyfd >= 0)
(void) loop_write(ttyfd, "(no echo) ", 10, false); (void) loop_write(ttyfd, NO_ECHO, strlen(NO_ECHO), false);
} else if (ttyfd >= 0) } else if (ttyfd >= 0)
(void) loop_write(ttyfd, "\a", 1, false); (void) loop_write(ttyfd, "\a", 1, false);
@ -619,7 +636,7 @@ int ask_password_tty(
/* ... or by pressing TAB at any time. */ /* ... or by pressing TAB at any time. */
if (ttyfd >= 0) if (ttyfd >= 0)
(void) loop_write(ttyfd, "(no echo) ", 10, false); (void) loop_write(ttyfd, NO_ECHO, strlen(NO_ECHO), false);
} else if (p >= sizeof(passphrase)-1) { } else if (p >= sizeof(passphrase)-1) {
@ -658,11 +675,15 @@ int ask_password_tty(
goto finish; goto finish;
skipped: skipped:
if (strv_isempty(l))
r = log_debug_errno(SYNTHETIC_ERRNO(ECANCELED), "Password query was cancelled.");
else {
if (keyname) if (keyname)
(void) add_to_keyring_and_log(keyname, flags, l); (void) add_to_keyring_and_log(keyname, flags, l);
*ret = TAKE_PTR(l); *ret = TAKE_PTR(l);
r = 0; r = 0;
}
finish: finish:
if (ttyfd >= 0 && reset_tty) { if (ttyfd >= 0 && reset_tty) {

View File

@ -580,7 +580,7 @@ static int remove_marked_symlinks_fd(
return -ENOMEM; return -ENOMEM;
path_simplify(p, false); path_simplify(p, false);
q = readlink_malloc(p, &dest); q = chase_symlinks(p, NULL, CHASE_NONEXISTENT, &dest, NULL);
if (q == -ENOENT) if (q == -ENOENT)
continue; continue;
if (q < 0) { if (q < 0) {
@ -1117,7 +1117,7 @@ static int config_parse_also(
void *data, void *data,
void *userdata) { void *userdata) {
UnitFileInstallInfo *info = userdata, *alsoinfo = NULL; UnitFileInstallInfo *info = userdata;
InstallContext *c = data; InstallContext *c = data;
int r; int r;
@ -1139,7 +1139,7 @@ static int config_parse_also(
if (r < 0) if (r < 0)
return r; return r;
r = install_info_add(c, printed, NULL, true, &alsoinfo); r = install_info_add(c, printed, NULL, true, NULL);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -257,7 +257,7 @@ static int parse_file(OrderedHashmap **sysctl_options, const char *path, bool ig
existing = ordered_hashmap_get(*sysctl_options, p); existing = ordered_hashmap_get(*sysctl_options, p);
if (existing) { if (existing) {
if (streq(value, existing->value)) { if (streq_ptr(value, existing->value)) {
existing->ignore_failure = existing->ignore_failure || ignore_failure; existing->ignore_failure = existing->ignore_failure || ignore_failure;
continue; continue;
} }

View File

@ -1,24 +1,26 @@
/* SPDX-License-Identifier: LGPL-2.1+ */ /* SPDX-License-Identifier: LGPL-2.1+ */
#include "alloc-util.h"
#include "ask-password-api.h" #include "ask-password-api.h"
#include "log.h"
#include "strv.h" #include "strv.h"
#include "tests.h"
static void ask_password(void) { static void test_ask_password(void) {
int r; int r;
_cleanup_strv_free_ char **ret = NULL; _cleanup_strv_free_ char **ret = NULL;
r = ask_password_tty(-1, "hello?", "da key", 0, 0, NULL, &ret); r = ask_password_tty(-1, "hello?", "da key", 0, ASK_PASSWORD_CONSOLE_COLOR, NULL, &ret);
assert(r >= 0); if (r == -ECANCELED)
assert(strv_length(ret) == 1); assert_se(ret == NULL);
else {
log_info("Got %s", *ret); assert_se(r >= 0);
assert_se(strv_length(ret) == 1);
log_info("Got \"%s\"", *ret);
}
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
log_parse_environment(); test_setup_logging(LOG_DEBUG);
ask_password(); test_ask_password();
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }