Code cleanup

This commit is contained in:
Michiel Broek 2005-07-14 19:22:13 +00:00
parent 5251b5f5fc
commit 9a3c47f15d
2 changed files with 344 additions and 350 deletions

View File

@ -1,13 +1,12 @@
/***************************************************************************** /*****************************************************************************
* *
* File ..................: mbuseradd/commonio.c * $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite * Purpose ...............: MBSE BBS Shadow Password Suite
* Last modification date : 09-Aug-2001
* Original Source .......: Shadow Password Suite * Original Source .......: Shadow Password Suite
* Original Copyrioght ...: Julianne Frances Haugh and others. * Original Copyright ....: Julianne Frances Haugh and others.
* *
***************************************************************************** *****************************************************************************
* Copyright (C) 1997-2001 * Copyright (C) 1997-2005
* *
* Michiel Broek FIDO: 2:280/2802 * Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10 * Beekmansbos 10

View File

@ -5,7 +5,7 @@
* Shadow Suite (c) ......: Julianne Frances Haugh * Shadow Suite (c) ......: Julianne Frances Haugh
* *
***************************************************************************** *****************************************************************************
* Copyright (C) 1997-2004 * Copyright (C) 1997-2005
* *
* Michiel Broek FIDO: 2:280/2802 * Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10 * Beekmansbos 10
@ -181,52 +181,52 @@ usage(void)
static void setup_tty(void) static void setup_tty(void)
{ {
TERMIO termio; TERMIO termio;
GTTY(0, &termio); /* get terminal characteristics */ GTTY(0, &termio); /* get terminal characteristics */
/* /*
* Add your favorite terminal modes here ... * Add your favorite terminal modes here ...
*/ */
termio.c_lflag |= ISIG|ICANON|ECHO|ECHOE; termio.c_lflag |= ISIG|ICANON|ECHO|ECHOE;
termio.c_iflag |= ICRNL; termio.c_iflag |= ICRNL;
#if defined(ECHOKE) && defined(ECHOCTL) #if defined(ECHOKE) && defined(ECHOCTL)
termio.c_lflag |= ECHOKE|ECHOCTL; termio.c_lflag |= ECHOKE|ECHOCTL;
#endif #endif
#if defined(ECHOPRT) && defined(NOFLSH) && defined(TOSTOP) #if defined(ECHOPRT) && defined(NOFLSH) && defined(TOSTOP)
termio.c_lflag &= ~(ECHOPRT|NOFLSH|TOSTOP); termio.c_lflag &= ~(ECHOPRT|NOFLSH|TOSTOP);
#endif #endif
#ifdef ONLCR #ifdef ONLCR
termio.c_oflag |= ONLCR; termio.c_oflag |= ONLCR;
#endif #endif
#ifdef SUN4 #ifdef SUN4
/* /*
* Terminal setup for SunOS 4.1 courtesy of Steve Allen * Terminal setup for SunOS 4.1 courtesy of Steve Allen
* at UCO/Lick. * at UCO/Lick.
*/ */
termio.c_cc[VEOF] = '\04'; termio.c_cc[VEOF] = '\04';
termio.c_cflag &= ~CSIZE; termio.c_cflag &= ~CSIZE;
termio.c_cflag |= (PARENB|CS7); termio.c_cflag |= (PARENB|CS7);
termio.c_lflag |= (ISIG|ICANON|ECHO|IEXTEN); termio.c_lflag |= (ISIG|ICANON|ECHO|IEXTEN);
termio.c_iflag |= (BRKINT|IGNPAR|ISTRIP|IMAXBEL|ICRNL|IXON); termio.c_iflag |= (BRKINT|IGNPAR|ISTRIP|IMAXBEL|ICRNL|IXON);
termio.c_iflag &= ~IXANY; termio.c_iflag &= ~IXANY;
termio.c_oflag |= (XTABS|OPOST|ONLCR); termio.c_oflag |= (XTABS|OPOST|ONLCR);
#endif #endif
/* leave these values unchanged if not specified in login.defs */ /* leave these values unchanged if not specified in login.defs */
termio.c_cc[VERASE] = getdef_num("ERASECHAR", termio.c_cc[VERASE]); termio.c_cc[VERASE] = getdef_num("ERASECHAR", termio.c_cc[VERASE]);
termio.c_cc[VKILL] = getdef_num("KILLCHAR", termio.c_cc[VKILL]); termio.c_cc[VKILL] = getdef_num("KILLCHAR", termio.c_cc[VKILL]);
/* /*
* ttymon invocation prefers this, but these settings won't come into * ttymon invocation prefers this, but these settings won't come into
* effect after the first username login * effect after the first username login
*/ */
STTY(0, &termio); STTY(0, &termio);
} }
@ -241,7 +241,6 @@ static void check_flags(int argc, char * const *argv)
* clever rlogin, telnet, and getty holes. * clever rlogin, telnet, and getty holes.
*/ */
for (arg = 1; arg < argc; arg++) { for (arg = 1; arg < argc; arg++) {
// printf("%d <%s>\n", arg, argv[arg]);
if (argv[arg][0] == '-' && strlen(argv[arg]) > 2) if (argv[arg][0] == '-' && strlen(argv[arg]) > 2)
usage(); usage();
} }
@ -251,83 +250,83 @@ static void check_flags(int argc, char * const *argv)
static void check_nologin(void) static void check_nologin(void)
{ {
char *fname; char *fname;
/*
* Check to see if system is turned off for non-root users.
* This would be useful to prevent users from logging in
* during system maintenance. We make sure the message comes
* out for root so she knows to remove the file if she's
* forgotten about it ...
*/
fname = getdef_str("NOLOGINS_FILE");
if (access(fname, F_OK) == 0) {
FILE *nlfp;
int c;
/* /*
* Check to see if system is turned off for non-root users. * Cat the file if it can be opened, otherwise just
* This would be useful to prevent users from logging in * print a default message
* during system maintenance. We make sure the message comes
* out for root so she knows to remove the file if she's
* forgotten about it ...
*/ */
fname = getdef_str("NOLOGINS_FILE"); if ((nlfp = fopen (fname, "r"))) {
if (access(fname, F_OK) == 0) { while ((c = getc (nlfp)) != EOF) {
FILE *nlfp; if (c == '\n')
int c; putchar ('\r');
/* putchar (c);
* Cat the file if it can be opened, otherwise just }
* print a default message fflush (stdout);
*/ fclose (nlfp);
} else
if ((nlfp = fopen (fname, "r"))) { printf("\nSystem closed for routine maintenance\n");
while ((c = getc (nlfp)) != EOF) {
if (c == '\n')
putchar ('\r');
putchar (c);
}
fflush (stdout);
fclose (nlfp);
} else
printf("\nSystem closed for routine maintenance\n");
free(fname);
closelog();
exit(0);
}
free(fname); free(fname);
closelog();
exit(0);
}
free(fname);
} }
static void init_env(void) static void init_env(void)
{ {
char *cp, *tmp; char *cp, *tmp;
if ((tmp = getenv("LANG"))) { if ((tmp = getenv("LANG"))) {
addenv("LANG", tmp); addenv("LANG", tmp);
} }
/* /*
* Add the timezone environmental variable so that time functions * Add the timezone environmental variable so that time functions
* work correctly. * work correctly.
*/ */
if ((tmp = getenv("TZ"))) { if ((tmp = getenv("TZ"))) {
addenv("TZ", tmp); addenv("TZ", tmp);
} }
/* /*
* Add the clock frequency so that profiling commands work * Add the clock frequency so that profiling commands work
* correctly. * correctly.
*/ */
if ((tmp = getenv("HZ"))) { if ((tmp = getenv("HZ"))) {
addenv("HZ", tmp); addenv("HZ", tmp);
} else if ((cp = getdef_str("ENV_HZ"))) { } else if ((cp = getdef_str("ENV_HZ"))) {
addenv(cp, NULL); addenv(cp, NULL);
} }
} }
static RETSIGTYPE alarm_handler(int sig) static RETSIGTYPE alarm_handler(int sig)
{ {
fprintf(stderr, "\nLogin timed out after %d seconds.\n", timeout); fprintf(stderr, "\nLogin timed out after %d seconds.\n", timeout);
exit(0); exit(0);
} }
@ -345,134 +344,134 @@ static RETSIGTYPE alarm_handler(int sig)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char username[37]; char username[37];
char tty[BUFSIZ]; char tty[BUFSIZ];
char userfile[PATH_MAX]; char userfile[PATH_MAX];
FILE *ufp; FILE *ufp;
int reason = PW_LOGIN; int reason = PW_LOGIN;
int delay; int delay;
int retries; int retries;
int failed; int failed;
int flag; int flag;
int subroot = 0; int subroot = 0;
int is_console = 0; int is_console = 0;
int FoundName; int FoundName;
const char *cp; const char *cp;
char *tmp; char *tmp;
char fromhost[512]; char fromhost[512];
struct passwd *pwd; struct passwd *pwd;
char **envp = environ; char **envp = environ;
static char temp_pw[2]; static char temp_pw[2];
static char temp_shell[] = "/bin/sh"; static char temp_shell[] = "/bin/sh";
#ifdef SHADOW_PASSWORD #ifdef SHADOW_PASSWORD
struct spwd *spwd=NULL; struct spwd *spwd=NULL;
#endif #endif
#if defined(DES_RPC) || defined(KERBEROS) #if defined(DES_RPC) || defined(KERBEROS)
/* from pwauth.c */ /* from pwauth.c */
extern char *clear_pass; extern char *clear_pass;
extern int wipe_clear_pass; extern int wipe_clear_pass;
/* /*
* We may need the password later, don't want pw_auth() to wipe it * We may need the password later, don't want pw_auth() to wipe it
* (we do it ourselves when it is no longer needed). --marekm * (we do it ourselves when it is no longer needed). --marekm
*/ */
wipe_clear_pass = 0; wipe_clear_pass = 0;
#endif #endif
/* /*
* Some quick initialization. * Some quick initialization.
*/ */
sanitize_env(); sanitize_env();
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR); bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE); textdomain(PACKAGE);
initenv(); initenv();
username[0] = '\0'; username[0] = '\0';
amroot = (getuid() == 0); amroot = (getuid() == 0);
Prog = Basename(argv[0]); Prog = Basename(argv[0]);
check_flags(argc, argv); check_flags(argc, argv);
while ((flag = getopt(argc, argv, "d:h:p")) != EOF) { while ((flag = getopt(argc, argv, "d:h:p")) != EOF) {
switch (flag) { switch (flag) {
case 'p': case 'p':
pflg++; pflg++;
break; break;
case 'h': case 'h':
hflg++; hflg++;
hostname = optarg; hostname = optarg;
reason = PW_TELNET; reason = PW_TELNET;
break; break;
case 'd': case 'd':
/* "-d device" ignored for compatibility */ /* "-d device" ignored for compatibility */
break; break;
default: default:
usage(); usage();
}
} }
}
/*
* Allow authentication bypass only if real UID is zero.
*/
if (hflg && !amroot) {
fprintf(stderr, _("%s: permission denied\n"), Prog);
exit(1);
}
if (!isatty(0) || !isatty(1) || !isatty(2))
exit(1); /* must be a terminal */
if (hflg) {
/* /*
* Allow authentication bypass only if real UID is zero. * Only show this before a prompt from telnetd
*/ */
if (hflg && !amroot) { printf("\nMBSE BBS v%s (Release: %s)\n", VERSION, ReleaseDate);
fprintf(stderr, _("%s: permission denied\n"), Prog); printf("%s\n\n", COPYRIGHT);
exit(1); }
}
if (!isatty(0) || !isatty(1) || !isatty(2)) /*
exit(1); /* must be a terminal */ * Be picky if run by normal users (possible if installed setuid
* root), but not if run by root. This way it still allows logins
* even if your getty is broken, or if something corrupts utmp,
* but users must "exec login" which will use the existing utmp
* entry (will not overwrite remote hostname). --marekm
*/
checkutmp(!amroot);
STRFCPY(tty, utent.ut_line);
if (hflg) { if (hflg) {
/*
* Only show this before a prompt from telnetd
*/
printf("\nMBSE BBS v%s (Release: %s)\n", VERSION, ReleaseDate);
printf("%s\n\n", COPYRIGHT);
}
/*
* Be picky if run by normal users (possible if installed setuid
* root), but not if run by root. This way it still allows logins
* even if your getty is broken, or if something corrupts utmp,
* but users must "exec login" which will use the existing utmp
* entry (will not overwrite remote hostname). --marekm
*/
checkutmp(!amroot);
STRFCPY(tty, utent.ut_line);
if (hflg) {
#ifdef UT_ADDR #ifdef UT_ADDR
struct hostent *he; struct hostent *he;
/* /*
* Fill in the ut_addr field (remote login IP address). * Fill in the ut_addr field (remote login IP address).
* XXX - login from util-linux does it, but this is not * XXX - login from util-linux does it, but this is not
* the right place to do it. The program that starts * the right place to do it. The program that starts
* login (telnetd, rlogind) knows the IP address, so it * login (telnetd, rlogind) knows the IP address, so it
* should create the utmp entry and fill in ut_addr. * should create the utmp entry and fill in ut_addr.
* gethostbyname() is not 100% reliable (the remote host * gethostbyname() is not 100% reliable (the remote host
* may be unknown, etc.). --marekm * may be unknown, etc.). --marekm
*/ */
if ((he = gethostbyname(hostname))) { if ((he = gethostbyname(hostname))) {
utent.ut_addr = *((int32_t *)(he->h_addr_list[0])); utent.ut_addr = *((int32_t *)(he->h_addr_list[0]));
#endif #endif
#ifdef UT_HOST #ifdef UT_HOST
strncpy(utent.ut_host, hostname, sizeof(utent.ut_host)); strncpy(utent.ut_host, hostname, sizeof(utent.ut_host));
#endif #endif
#if HAVE_UTMPX_H #if HAVE_UTMPX_H
strncpy(utxent.ut_host, hostname, sizeof(utxent.ut_host)); strncpy(utxent.ut_host, hostname, sizeof(utxent.ut_host));
#endif #endif
/* /*
* Add remote hostname to the environment. I think * Add remote hostname to the environment. I think
* (not sure) I saw it once on Irix. --marekm * (not sure) I saw it once on Irix. --marekm
*/ */
addenv("REMOTEHOST", hostname); addenv("REMOTEHOST", hostname);
} }
#ifdef __linux__ #ifdef __linux__
/* workaround for init/getty leaving junk in ut_host at least in some /* workaround for init/getty leaving junk in ut_host at least in some
@ -491,13 +490,13 @@ int main(int argc, char **argv)
/* preserve TERM from getty */ /* preserve TERM from getty */
if (!pflg && (tmp = getenv("TERM"))) if (!pflg && (tmp = getenv("TERM")))
addenv("TERM", tmp); addenv("TERM", tmp);
/* preserver CONNECT messages from mgetty */ /* preserver CONNECT messages from mgetty */
if ((tmp = getenv("CONNECT"))) if ((tmp = getenv("CONNECT")))
addenv("CONNECT", tmp); addenv("CONNECT", tmp);
if ((tmp = getenv("CALLER_ID"))) if ((tmp = getenv("CALLER_ID")))
addenv("CALLER_ID", tmp); addenv("CALLER_ID", tmp);
/* get the mbse environment */ /* get the mbse environment */
pw = getpwnam("mbse"); pw = getpwnam("mbse");
@ -509,8 +508,6 @@ int main(int argc, char **argv)
init_env(); init_env();
if (optind < argc) { /* get the user name */ if (optind < argc) { /* get the user name */
// if (rflg || fflg)
// usage();
#ifdef SVR4 #ifdef SVR4
/* /*
@ -527,8 +524,6 @@ int main(int argc, char **argv)
} }
} }
// printf("[%s]\n", username);
#ifdef SVR4 #ifdef SVR4
/* /*
* check whether ttymon has done the prompt for us already * check whether ttymon has done the prompt for us already
@ -544,222 +539,222 @@ int main(int argc, char **argv)
} }
#endif /* SVR4 */ #endif /* SVR4 */
if (optind < argc) /* now set command line variables */ if (optind < argc) /* now set command line variables */
set_env(argc - optind, &argv[optind]); set_env(argc - optind, &argv[optind]);
if (hflg) if (hflg)
cp = hostname; cp = hostname;
else else
#ifdef UT_HOST #ifdef UT_HOST
if (utent.ut_host[0]) if (utent.ut_host[0])
cp = utent.ut_host; cp = utent.ut_host;
else else
#endif #endif
#if HAVE_UTMPX_H #if HAVE_UTMPX_H
if (utxent.ut_host[0]) if (utxent.ut_host[0])
cp = utxent.ut_host; cp = utxent.ut_host;
else else
#endif #endif
cp = ""; cp = "";
if (*cp) if (*cp)
snprintf(fromhost, sizeof fromhost, _(" on `%s' from `%s'"), tty, cp); snprintf(fromhost, sizeof fromhost, _(" on `%s' from `%s'"), tty, cp);
else else
snprintf(fromhost, sizeof fromhost, _(" on `%s'"), tty); snprintf(fromhost, sizeof fromhost, _(" on `%s'"), tty);
top: top:
/* only allow ALARM sec. for login */ /* only allow ALARM sec. for login */
signal(SIGALRM, alarm_handler); signal(SIGALRM, alarm_handler);
timeout = getdef_num("LOGIN_TIMEOUT", ALARM); timeout = getdef_num("LOGIN_TIMEOUT", ALARM);
if (timeout > 0) if (timeout > 0)
alarm(timeout); alarm(timeout);
environ = newenvp; /* make new environment active */ environ = newenvp; /* make new environment active */
delay = getdef_num("FAIL_DELAY", 1); delay = getdef_num("FAIL_DELAY", 1);
retries = getdef_num("LOGIN_RETRIES", RETRIES); retries = getdef_num("LOGIN_RETRIES", RETRIES);
while (1) { /* repeatedly get login/password pairs */ while (1) { /* repeatedly get login/password pairs */
failed = 0; /* haven't failed authentication yet */ failed = 0; /* haven't failed authentication yet */
if (! username[0]) { /* need to get a login id */ if (! username[0]) { /* need to get a login id */
if (subroot) { if (subroot) {
closelog (); closelog ();
exit (1); exit (1);
}
preauth_flag = 0;
login_prompt(_("login: "), username, sizeof username);
continue;
} }
preauth_flag = 0;
login_prompt(_("login: "), username, sizeof username);
continue;
}
/* /*
* Here we try usernames on unix names and Fidonet style * Here we try usernames on unix names and Fidonet style
* names that are stored in the bbs userdatabase. * names that are stored in the bbs userdatabase.
* The name "bbs" is for new users, don't check the bbs userfile. * The name "bbs" is for new users, don't check the bbs userfile.
* If allowed from login.defs accept the name "mbse". * If allowed from login.defs accept the name "mbse".
*/ */
FoundName = 0; FoundName = 0;
if (strcmp(username, getdef_str("NEWUSER_ACCOUNT")) == 0) { if (strcmp(username, getdef_str("NEWUSER_ACCOUNT")) == 0) {
FoundName = 1; FoundName = 1;
} }
if ((getdef_bool("ALLOW_MBSE") != 0) && (strcmp(username, "mbse") == 0)) { if ((getdef_bool("ALLOW_MBSE") != 0) && (strcmp(username, "mbse") == 0)) {
FoundName = 1; FoundName = 1;
} }
if (! FoundName) { if (! FoundName) {
if ((ufp = fopen(userfile, "r"))) { if ((ufp = fopen(userfile, "r"))) {
fread(&usrconfighdr, sizeof(usrconfighdr), 1, ufp); fread(&usrconfighdr, sizeof(usrconfighdr), 1, ufp);
while (fread(&usrconfig, usrconfighdr.recsize, 1, ufp) == 1) { while (fread(&usrconfig, usrconfighdr.recsize, 1, ufp) == 1) {
if ((strcasecmp(usrconfig.sUserName, username) == 0) || if ((strcasecmp(usrconfig.sUserName, username) == 0) ||
(strcasecmp(usrconfig.sHandle, username) == 0) || (strcasecmp(usrconfig.sHandle, username) == 0) ||
(strcmp(usrconfig.Name, username) == 0)) { (strcmp(usrconfig.Name, username) == 0)) {
FoundName = 1;
STRFCPY(username, usrconfig.Name);
break;
}
}
fclose(ufp);
}
}
if (!FoundName) {
if (getdef_bool("ASK_NEWUSER") != 0) {
/*
* User entered none excisting name, offer him/her the choice
* to register as a new user.
*/
login_prompt(_("Do you want to register as new user? [y/N]: "), username, sizeof username);
if ((username[0] && (toupper(username[0]) == 'Y'))) {
FoundName = 1; FoundName = 1;
preauth_flag = 0; STRFCPY(username, usrconfig.Name);
STRFCPY(username, getdef_str("NEWUSER_ACCOUNT")); break;
syslog(LOG_WARNING, "unknown user wants to register");
} }
} }
fclose(ufp);
} }
}
if ((! (pwd = getpwnam(username))) || (FoundName == 0)) { if (!FoundName) {
pwent.pw_name = username; if (getdef_bool("ASK_NEWUSER") != 0) {
strcpy(temp_pw, "!"); /*
pwent.pw_passwd = temp_pw; * User entered none excisting name, offer him/her the choice
pwent.pw_shell = temp_shell; * to register as a new user.
*/
login_prompt(_("Do you want to register as new user? [y/N]: "), username, sizeof username);
if ((username[0] && (toupper(username[0]) == 'Y'))) {
FoundName = 1;
preauth_flag = 0; preauth_flag = 0;
failed = 1; STRFCPY(username, getdef_str("NEWUSER_ACCOUNT"));
} else { syslog(LOG_WARNING, "unknown user wants to register");
pwent = *pwd; }
} }
}
if ((! (pwd = getpwnam(username))) || (FoundName == 0)) {
pwent.pw_name = username;
strcpy(temp_pw, "!");
pwent.pw_passwd = temp_pw;
pwent.pw_shell = temp_shell;
preauth_flag = 0;
failed = 1;
} else {
pwent = *pwd;
}
#ifdef SHADOW_PASSWORD #ifdef SHADOW_PASSWORD
spwd = NULL; spwd = NULL;
if (pwd && strcmp(pwd->pw_passwd, SHADOW_PASSWD_STRING) == 0) { if (pwd && strcmp(pwd->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
spwd = getspnam(username); spwd = getspnam(username);
if (spwd) if (spwd)
pwent.pw_passwd = spwd->sp_pwdp; pwent.pw_passwd = spwd->sp_pwdp;
else else
syslog(LOG_WARNING, NO_SHADOW, username, fromhost); syslog(LOG_WARNING, NO_SHADOW, username, fromhost);
} }
#endif /* SHADOWPWD */ #endif /* SHADOWPWD */
/* /*
* If the encrypted password begins with a "!", the account * If the encrypted password begins with a "!", the account
* is locked and the user cannot login, even if they have * is locked and the user cannot login, even if they have
* been "pre-authenticated." * been "pre-authenticated."
*/ */
if (pwent.pw_passwd[0] == '!' || pwent.pw_passwd[0] == '*') if (pwent.pw_passwd[0] == '!' || pwent.pw_passwd[0] == '*')
failed = 1;
/*
* The -r and -f flags provide a name which has already
* been authenticated by some server.
*/
if (preauth_flag)
goto auth_ok;
if (pw_auth(pwent.pw_passwd, username, reason, (char *) 0) == 0)
goto auth_ok;
/*
* Don't log unknown usernames - I mistyped the password for
* username at least once... Should probably use LOG_AUTHPRIV
* for those who really want to log them. --marekm
*/
syslog(LOG_WARNING, BAD_PASSWD, (pwd || getdef_bool("LOG_UNKFAIL_ENAB")) ? username : "UNKNOWN", fromhost);
failed = 1; failed = 1;
/*
* The -r and -f flags provide a name which has already
* been authenticated by some server.
*/
if (preauth_flag)
goto auth_ok;
if (pw_auth(pwent.pw_passwd, username, reason, (char *) 0) == 0)
goto auth_ok;
/*
* Don't log unknown usernames - I mistyped the password for
* username at least once... Should probably use LOG_AUTHPRIV
* for those who really want to log them. --marekm
*/
syslog(LOG_WARNING, BAD_PASSWD, (pwd || getdef_bool("LOG_UNKFAIL_ENAB")) ? username : "UNKNOWN", fromhost);
failed = 1;
auth_ok: auth_ok:
/* /*
* This is the point where all authenticated users * This is the point where all authenticated users
* wind up. If you reach this far, your password has * wind up. If you reach this far, your password has
* been authenticated and so on. * been authenticated and so on.
*/ */
#if defined(RADIUS) && !(defined(DES_RPC) || defined(KERBEROS)) #if defined(RADIUS) && !(defined(DES_RPC) || defined(KERBEROS))
if (clear_pass) { if (clear_pass) {
strzero(clear_pass); strzero(clear_pass);
clear_pass = NULL; clear_pass = NULL;
} }
#endif #endif
if (! failed && pwent.pw_name && pwent.pw_uid == 0 && ! is_console) { if (! failed && pwent.pw_name && pwent.pw_uid == 0 && ! is_console) {
syslog(LOG_CRIT, BAD_ROOT_LOGIN, fromhost); syslog(LOG_CRIT, BAD_ROOT_LOGIN, fromhost);
failed = 1; failed = 1;
} }
#ifdef LOGIN_ACCESS #ifdef LOGIN_ACCESS
if (!failed && !login_access(username, *hostname ? hostname : tty)) { if (!failed && !login_access(username, *hostname ? hostname : tty)) {
syslog(LOG_WARNING, LOGIN_REFUSED, username, fromhost); syslog(LOG_WARNING, LOGIN_REFUSED, username, fromhost);
failed = 1; failed = 1;
} }
#endif #endif
if (! failed) if (! failed)
break; break;
memzero(username, sizeof username); memzero(username, sizeof username);
if (--retries <= 0) if (--retries <= 0)
syslog(LOG_CRIT, MANY_FAILS, fromhost); syslog(LOG_CRIT, MANY_FAILS, fromhost);
#if 1 #if 1
/* /*
* If this was a passwordless account and we get here, * If this was a passwordless account and we get here,
* login was denied (securetty, faillog, etc.). There * login was denied (securetty, faillog, etc.). There
* was no password prompt, so do it now (will always * was no password prompt, so do it now (will always
* fail - the bad guys won't see that the passwordless * fail - the bad guys won't see that the passwordless
* account exists at all). --marekm * account exists at all). --marekm
*/ */
if (pwent.pw_passwd[0] == '\0') if (pwent.pw_passwd[0] == '\0')
pw_auth("!", username, reason, (char *) 0); pw_auth("!", username, reason, (char *) 0);
#endif #endif
/* /*
* Wait a while (a la SVR4 /usr/bin/login) before attempting * Wait a while (a la SVR4 /usr/bin/login) before attempting
* to login the user again. If the earlier alarm occurs * to login the user again. If the earlier alarm occurs
* before the sleep() below completes, login will exit. * before the sleep() below completes, login will exit.
*/ */
if (delay > 0) if (delay > 0)
sleep(delay); sleep(delay);
puts(_("Login incorrect")); puts(_("Login incorrect"));
} /* while (1) */ } /* while (1) */
(void) alarm (0); /* turn off alarm clock */ (void) alarm (0); /* turn off alarm clock */
if (getenv("IFS")) /* don't export user IFS ... */ if (getenv("IFS")) /* don't export user IFS ... */
addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */ addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
setutmp(username, tty, hostname); /* make entry in utmp & wtmp files */ setutmp(username, tty, hostname); /* make entry in utmp & wtmp files */
if (pwent.pw_shell[0] == '*') { /* subsystem root */ if (pwent.pw_shell[0] == '*') { /* subsystem root */
subsystem (&pwent); /* figure out what to execute */ subsystem (&pwent); /* figure out what to execute */
subroot++; /* say i was here again */ subroot++; /* say i was here again */
endpwent (); /* close all of the file which were */ endpwent (); /* close all of the file which were */
endgrent (); /* open in the original rooted file */ endgrent (); /* open in the original rooted file */
#ifdef SHADOW_PASSWORD #ifdef SHADOW_PASSWORD
endspent (); /* system. they will be re-opened */ endspent (); /* system. they will be re-opened */
#endif #endif
#ifdef SHADOWGRP #ifdef SHADOWGRP
endsgent (); /* in the new rooted file system */ endsgent (); /* in the new rooted file system */
#endif #endif
goto top; /* go do all this all over again */ goto top; /* go do all this all over again */
} }
if (getdef_bool("LASTLOG_ENAB")) /* give last login and log this one */ if (getdef_bool("LASTLOG_ENAB")) /* give last login and log this one */
dolastlog(&lastlog, &pwent, utent.ut_line, hostname); dolastlog(&lastlog, &pwent, utent.ut_line, hostname);
#ifdef SVR4_SI86_EUA #ifdef SVR4_SI86_EUA
sysi86(SI86LIMUSER, EUA_ADD_USER); /* how do we test for fail? */ sysi86(SI86LIMUSER, EUA_ADD_USER); /* how do we test for fail? */
@ -774,21 +769,21 @@ auth_ok:
*/ */
#ifdef SHADOW_PASSWORD #ifdef SHADOW_PASSWORD
if (spwd) { /* check for age of password */ if (spwd) { /* check for age of password */
if (expire (&pwent, spwd)) { if (expire (&pwent, spwd)) {
pwd = getpwnam(username); pwd = getpwnam(username);
spwd = getspnam(username); spwd = getspnam(username);
if (pwd) if (pwd)
pwent = *pwd; pwent = *pwd;
} }
} }
#else #else
#ifdef ATT_AGE #ifdef ATT_AGE
if (pwent.pw_age && pwent.pw_age[0]) { if (pwent.pw_age && pwent.pw_age[0]) {
if (expire (&pwent)) { if (expire (&pwent)) {
pwd = getpwnam(username); pwd = getpwnam(username);
if (pwd) if (pwd)
pwent = *pwd; pwent = *pwd;
} }
} }
#endif /* ATT_AGE */ #endif /* ATT_AGE */
#endif /* SHADOWPWD */ #endif /* SHADOWPWD */
@ -798,19 +793,19 @@ auth_ok:
chown_tty(tty, &pwent); chown_tty(tty, &pwent);
if (setup_uid_gid(&pwent, is_console)) if (setup_uid_gid(&pwent, is_console))
exit(1); exit(1);
#ifdef KERBEROS #ifdef KERBEROS
if (clear_pass) if (clear_pass)
login_kerberos(username, clear_pass); login_kerberos(username, clear_pass);
#endif #endif
#ifdef DES_RPC #ifdef DES_RPC
if (clear_pass) if (clear_pass)
login_desrpc(clear_pass); login_desrpc(clear_pass);
#endif #endif
#if defined(DES_RPC) || defined(KERBEROS) #if defined(DES_RPC) || defined(KERBEROS)
if (clear_pass) if (clear_pass)
strzero(clear_pass); strzero(clear_pass);
#endif #endif
setup_env(&pwent); /* set env vars, cd to the home dir */ setup_env(&pwent); /* set env vars, cd to the home dir */
@ -836,9 +831,9 @@ auth_ok:
endsgent(); /* stop access to shadow group file */ endsgent(); /* stop access to shadow group file */
#endif #endif
if (pwent.pw_uid == 0) if (pwent.pw_uid == 0)
syslog(LOG_NOTICE, ROOT_LOGIN, fromhost); syslog(LOG_NOTICE, ROOT_LOGIN, fromhost);
else else
syslog(LOG_INFO, REG_LOGIN, username, fromhost); syslog(LOG_INFO, REG_LOGIN, username, fromhost);
closelog(); closelog();
shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */ shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */