You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
5.7 KiB
175 lines
5.7 KiB
From a08c1a6aadaa27e4070fe58242d55464d6c7a3e7 Mon Sep 17 00:00:00 2001 |
|
From: Karel Zak <kzak@redhat.com> |
|
Date: Mon, 25 May 2015 15:30:52 +0200 |
|
Subject: [PATCH 164/173] sulogin: improve support for locked root account |
|
|
|
Some installations and distributions don't use a root account password |
|
for security reasons and use sudo instead. In that case, asking for the |
|
password makes no sense, and it is not even considered as valid as it's just |
|
"*" or "!". |
|
|
|
In these cases --force is required to just start a root shell and no |
|
ask for password. |
|
|
|
I don't think it's a good idea to automatically start root shell when |
|
locked account is detected. It's possible that the machine is on |
|
public place and for example Ubuntu uses root account disabled by |
|
default (and also Fedora when installed by yum/dnf without anaconda). |
|
|
|
The --force option forces admins to think about it... |
|
|
|
The distro maintainers can also use --force in their initscripts or |
|
systemd emergency.service if they believe that promiscuous setting is |
|
the right thing for the distro. |
|
|
|
Addresses: https://bugs.debian.org/326678 |
|
Addresses: http://bugzilla.redhat.com/show_bug.cgi?id=1561200 |
|
Upstream: http://github.com/karelzak/util-linux/commit/7ff1162e67164cb4ece19dd809c26272461aa254 |
|
Signed-off-by: Karel Zak <kzak@redhat.com> |
|
--- |
|
login-utils/sulogin.8 | 13 +++++++++---- |
|
login-utils/sulogin.c | 48 ++++++++++++++++++++++++++++++++++-------------- |
|
2 files changed, 43 insertions(+), 18 deletions(-) |
|
|
|
diff --git a/login-utils/sulogin.8 b/login-utils/sulogin.8 |
|
index b9dec165c..702487985 100644 |
|
--- a/login-utils/sulogin.8 |
|
+++ b/login-utils/sulogin.8 |
|
@@ -35,8 +35,10 @@ Give root password for system maintenance |
|
.br |
|
(or type Control\-D for normal startup): |
|
.PP |
|
-.I sulogin |
|
-will be connected to the current terminal, or to the optional tty device that |
|
+If the root account is locked and --force is specified, no password is required. |
|
+.PP |
|
+.B sulogin |
|
+will be connected to the current terminal, or to the optional \fItty\fR device that |
|
can be specified on the command line (typically |
|
.BR /dev/console ). |
|
.PP |
|
@@ -50,8 +52,11 @@ from the system fails, manually examine |
|
.I /etc/passwd |
|
and |
|
.I /etc/shadow |
|
-to get the password. If they are damaged or nonexistent, sulogin will start |
|
-a root shell without asking for a password. |
|
+to get the password. If these files are damaged or nonexistent, or when |
|
+root account is locked by '!' or '*' at the begin of the password then |
|
+.B sulogin |
|
+will \fBstart a root shell without asking for a password\fP. |
|
+.PP |
|
.IP |
|
Only use the |
|
.B \-e |
|
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c |
|
index 6d03bc5ae..a17b91d71 100644 |
|
--- a/login-utils/sulogin.c |
|
+++ b/login-utils/sulogin.c |
|
@@ -81,6 +81,13 @@ static volatile sig_atomic_t sigchild; |
|
# define IUCLC 0 |
|
#endif |
|
|
|
+static int locked_account_password(const char *passwd) |
|
+{ |
|
+ if (passwd && (*passwd == '*' || *passwd == '!')) |
|
+ return 1; |
|
+ return 0; |
|
+} |
|
+ |
|
/* |
|
* Fix the tty modes and set reasonable defaults. |
|
*/ |
|
@@ -423,7 +430,6 @@ static struct passwd *getrootpwent(int try_manually) |
|
p = line; |
|
break; |
|
} |
|
- |
|
fclose(fp); |
|
|
|
/* |
|
@@ -460,7 +466,8 @@ static struct passwd *getrootpwent(int try_manually) |
|
warnx(_("%s: no entry for root"), _PATH_SHADOW_PASSWD); |
|
*pwd.pw_passwd = '\0'; |
|
} |
|
- if (!valid(pwd.pw_passwd)) { |
|
+ /* locked accont passwords are valid too */ |
|
+ if (!locked_account_password(pwd.pw_passwd) && !valid(pwd.pw_passwd)) { |
|
warnx(_("%s: root password garbled"), _PATH_SHADOW_PASSWD); |
|
*pwd.pw_passwd = '\0'; |
|
} |
|
@@ -470,7 +477,7 @@ static struct passwd *getrootpwent(int try_manually) |
|
/* |
|
* Ask by prompt for the password. |
|
*/ |
|
-static void doprompt(const char *crypted, struct console *con) |
|
+static void doprompt(const char *crypted, struct console *con, int deny) |
|
{ |
|
struct termios tty; |
|
|
|
@@ -487,18 +494,25 @@ static void doprompt(const char *crypted, struct console *con) |
|
if ((con->file = fdopen(con->fd, "r+")) == (FILE*)0) |
|
goto err; |
|
} |
|
+ |
|
+ if (deny) |
|
+ fprintf(con->file, _("\nCannot open access to console, the root account is locked.\n" |
|
+ "See sulogin(8) man page for more details.\n\n" |
|
+ "Press Enter to continue.\n")); |
|
+ else { |
|
#if defined(USE_ONELINE) |
|
- if (crypted[0]) |
|
- fprintf(con->file, _("Give root password for login: ")); |
|
- else |
|
- fprintf(con->file, _("Press enter for login: ")); |
|
+ if (crypted[0] && !locked_account_password(crypted)) |
|
+ fprintf(con->file, _("Give root password for login: ")); |
|
+ else |
|
+ fprintf(con->file, _("Press Enter for login: ")); |
|
#else |
|
- if (crypted[0]) |
|
- fprintf(con->file, _("Give root password for maintenance\n")); |
|
- else |
|
- fprintf(con->file, _("Press enter for maintenance")); |
|
- fprintf(con->file, _("(or type Control-D to continue): ")); |
|
+ if (crypted[0] && !locked_account_password(crypted)) |
|
+ fprintf(con->file, _("Give root password for maintenance\n")); |
|
+ else |
|
+ fprintf(con->file, _("Press Enter for maintenance\n")); |
|
+ fprintf(con->file, _("(or press Control-D to continue): ")); |
|
#endif |
|
+ } |
|
fflush(con->file); |
|
err: |
|
if (con->flags & CON_SERIAL) |
|
@@ -914,6 +928,7 @@ int main(int argc, char **argv) |
|
goto nofork; |
|
} |
|
|
|
+ |
|
mask_signal(SIGCHLD, chld_handler, &saved_sigchld); |
|
do { |
|
con = list_entry(ptr, struct console, entry); |
|
@@ -930,12 +945,17 @@ int main(int argc, char **argv) |
|
const char *passwd = pwd->pw_passwd; |
|
const char *answer; |
|
int failed = 0, doshell = 0; |
|
+ int deny = !opt_e && locked_account_password(pwd->pw_passwd); |
|
+ |
|
+ doprompt(passwd, con, deny); |
|
|
|
- doprompt(passwd, con); |
|
if ((answer = getpasswd(con)) == NULL) |
|
break; |
|
+ if (deny) |
|
+ exit(EXIT_FAILURE); |
|
|
|
- if (passwd[0] == '\0') |
|
+ /* no password or locked account */ |
|
+ if (!passwd[0] || locked_account_password(passwd)) |
|
doshell++; |
|
else { |
|
const char *cryptbuf; |
|
-- |
|
2.14.4 |
|
|
|
|