various: try to use DEFAULT_USER_SHELL for root too
/bin/sh as a shell is punishing. There is no good reason to make
the occasional root login unpleasant.
Since /bin/sh is usually /bin/bash in compat mode, i.e. if one is
available, the other will be too, /bin/bash is almost as good as a default.
But to avoid a regression in the situation where /bin/bash (or
DEFAULT_USER_SHELL) is not installed, we check with access() and fall back
to /bin/sh. This should make this change in behaviour less risky.
(FWIW, e.g. Fedora/RHEL use /bin/bash as default for root.)
This is a follow-up of sorts for 53350c7bba,
which added the default-user-shell option, but most likely with the idea
of using /bin/bash less ;)
Fixes #24369.
This commit is contained in:
+18
-3
@@ -13,6 +13,7 @@
|
||||
#include "sd-messages.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "chase-symlinks.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@@ -136,7 +137,6 @@ char *getusername_malloc(void) {
|
||||
}
|
||||
|
||||
bool is_nologin_shell(const char *shell) {
|
||||
|
||||
return PATH_IN_SET(shell,
|
||||
/* 'nologin' is the friendliest way to disable logins for a user account. It prints a nice
|
||||
* message and exits. Different distributions place the binary at different places though,
|
||||
@@ -154,6 +154,21 @@ bool is_nologin_shell(const char *shell) {
|
||||
"/usr/bin/true");
|
||||
}
|
||||
|
||||
const char* default_root_shell(const char *root) {
|
||||
/* We want to use the preferred shell, i.e. DEFAULT_USER_SHELL, which usually
|
||||
* will be /bin/bash. Fall back to /bin/sh if DEFAULT_USER_SHELL is not found,
|
||||
* or any access errors. */
|
||||
|
||||
int r = chase_symlinks(DEFAULT_USER_SHELL, root, CHASE_PREFIX_ROOT, NULL, NULL);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
log_debug_errno(r, "Failed to look up shell '%s%s%s': %m",
|
||||
strempty(root), root ? "/" : "", DEFAULT_USER_SHELL);
|
||||
if (r > 0)
|
||||
return DEFAULT_USER_SHELL;
|
||||
|
||||
return "/bin/sh";
|
||||
}
|
||||
|
||||
static int synthesize_user_creds(
|
||||
const char **username,
|
||||
uid_t *uid, gid_t *gid,
|
||||
@@ -176,7 +191,7 @@ static int synthesize_user_creds(
|
||||
*home = "/root";
|
||||
|
||||
if (shell)
|
||||
*shell = "/bin/sh";
|
||||
*shell = default_root_shell(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -635,7 +650,7 @@ int get_shell(char **_s) {
|
||||
/* Hardcode shell for root and nobody to avoid NSS */
|
||||
u = getuid();
|
||||
if (u == 0) {
|
||||
s = strdup("/bin/sh");
|
||||
s = strdup(default_root_shell(NULL));
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@@ -130,6 +130,7 @@ int putsgent_sane(const struct sgrp *sg, FILE *stream);
|
||||
#endif
|
||||
|
||||
bool is_nologin_shell(const char *shell);
|
||||
const char* default_root_shell(const char *root);
|
||||
|
||||
int is_this_me(const char *username);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user