diff options
-rw-r--r-- | login-utils/sulogin.8 | 8 | ||||
-rw-r--r-- | login-utils/sulogin.c | 48 |
2 files changed, 40 insertions, 16 deletions
diff --git a/login-utils/sulogin.8 b/login-utils/sulogin.8 index 17b07da65..9bc2effce 100644 --- a/login-utils/sulogin.8 +++ b/login-utils/sulogin.8 @@ -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 @@ -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 diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c index f376bfc45..be52141c1 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; +} + #ifdef TIOCGLCKTRMIOS /* * For the case plymouth is found on this system @@ -485,7 +492,6 @@ static struct passwd *getrootpwent(int try_manually) p = line; break; } - fclose(fp); /* @@ -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'; } @@ -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; @@ -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) @@ -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); @@ -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; |