Skip to content

Commit

Permalink
sulogin: improve support for locked root account
Browse files Browse the repository at this point in the history
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
Signed-off-by: Karel Zak <kzak@redhat.com>
  • Loading branch information
karelzak committed Jun 25, 2015
1 parent 13c551f commit 7ff1162
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 16 deletions.
8 changes: 6 additions & 2 deletions login-utils/sulogin.8
Expand Up @@ -33,6 +33,8 @@ Give root password for system maintenance
.br
(or type Control\-D for normal startup):
.PP
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
Expand All @@ -48,9 +50,11 @@ fails, then examine
.I /etc/passwd
and
.I /etc/shadow
to get the password. If these files are damaged or nonexistent,
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 start a root shell without asking for a password.
will \fBstart a root shell without asking for a password\fP.
.PP
.IP
Only use the
.B \-e
Expand Down
48 changes: 34 additions & 14 deletions login-utils/sulogin.c
Expand Up @@ -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;
}

#ifdef TIOCGLCKTRMIOS
/*
* For the case plymouth is found on this system
Expand Down Expand Up @@ -485,7 +492,6 @@ static struct passwd *getrootpwent(int try_manually)
p = line;
break;
}

fclose(fp);

/*
Expand Down Expand Up @@ -522,7 +528,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';
}
Expand All @@ -532,7 +539,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;

Expand All @@ -549,18 +556,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 press 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)
Expand Down Expand Up @@ -980,6 +994,7 @@ int main(int argc, char **argv)
goto nofork;
}


mask_signal(SIGCHLD, chld_handler, &saved_sigchld);
do {
con = list_entry(ptr, struct console, entry);
Expand All @@ -996,12 +1011,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;
Expand Down

0 comments on commit 7ff1162

Please sign in to comment.