diff options
Diffstat (limited to 'src/appl/bsd/login.c')
-rw-r--r-- | src/appl/bsd/login.c | 194 |
1 files changed, 157 insertions, 37 deletions
diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c index cc7a4bec6f..a2ba6f39d2 100644 --- a/src/appl/bsd/login.c +++ b/src/appl/bsd/login.c @@ -1,7 +1,5 @@ /* - * $Source$ - * $Author$ - * $Id$ + * appl/bsd/login.c */ /* @@ -59,14 +57,28 @@ static char sccsid[] = "@(#)login.c 5.25 (Berkeley) 1/6/89"; #include <sys/resource.h> #include <sys/file.h> #include <sys/ioctl.h> +#include <fcntl.h> +#ifdef NEED_SYS_FCNTL_H +#include <sys/fcntl.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif #include <utmp.h> #include <signal.h> -#if !defined(_AIX) +#ifdef HAVE_LASTLOG_H #include <lastlog.h> #endif +#ifdef linux +/* linux has V* but not C* in headers. Perhaps we shouldn't be + * initializing these values anyway -- tcgetattr *should* give + * them reasonable defaults... */ +#define NO_INIT_CC +#endif + #include <errno.h> #ifdef HAVE_TTYENT_H #include <ttyent.h> @@ -86,9 +98,12 @@ static char sccsid[] = "@(#)login.c 5.25 (Berkeley) 1/6/89"; #include <arpa/resolv.h> #endif /* BIND_HACK */ #endif /* KRB4 */ +#include "loginpaths.h" #ifdef POSIX #include <stdlib.h> +#endif +#ifdef POSIX_TERMIOS #include <termios.h> #ifdef _AIX #include <termio.h> @@ -100,21 +115,36 @@ static char sccsid[] = "@(#)login.c 5.25 (Berkeley) 1/6/89"; #include <sys/id.h> #endif +#ifndef HAVE_GETDTABLESIZE +#include <sys/resource.h> +int getdtablesize() { + struct rlimit rl; + getrlimit(RLIMIT_NOFILE, &rl); + return rl.rlim_cur; +} +#endif + #if defined(_AIX) #define PRIO_OFFSET 20 #else #define PRIO_OFFSET 0 #endif -#ifdef UIDGID_T -uid_t getuid(); +/* XXX -- do we ever need to test for these? */ #define uid_type uid_t #define gid_type gid_t -#else -int getuid(); -#define uid_type int -#define gid_type int -#endif /* UIDGID_T */ + +#ifndef HAVE_INITGROUPS +/* sco has getgroups and setgroups but no initgroups */ +int initgroups(char* name, gid_t basegid) { + gid_t others[NGROUPS_MAX+1]; + int ngrps; + + others[0] = basegid; + ngrps = getgroups(NGROUPS_MAX, others+1); + return setgroups(ngrps+1, others); +} +#endif #define TTYGRPNAME "tty" /* name of group to own ttys */ @@ -138,8 +168,13 @@ int getuid(); #define REGISTER "/usr/etc/go_register" #define GET_MOTD "/bin/athena/get_message" +#ifndef NO_UT_HOST #define UT_HOSTSIZE sizeof(((struct utmp *)0)->ut_host) +#endif +#ifndef UT_NAMESIZE +/* linux defines it directly in <utmp.h> */ #define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name) +#endif #define MAXENVIRON 32 @@ -152,7 +187,7 @@ int timeout = 300; struct passwd *pwd; char term[64], *hostname, *username; -#ifndef POSIX +#ifndef POSIX_TERMIOS struct sgttyb sgttyb; struct tchars tc = { CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK @@ -182,7 +217,6 @@ int pagflag = 0; /* true if setpag() has been called */ #endif /* KRB4 */ char *getenv(); -char *strsave(); void dofork(); #ifdef POSIX @@ -219,9 +253,9 @@ main(argc, argv) char *domain, *salt, **envinit, *ttyn, *tty, *ktty; char tbuf[MAXPATHLEN + 2]; char *ttyname(), *stypeof(), *crypt(), *getpass(); - time_t time(), login_time; + time_t login_time; off_t lseek(); -#ifdef POSIX +#ifdef POSIX_TERMIOS struct termios tc; #endif @@ -229,7 +263,9 @@ main(argc, argv) (void)alarm((u_int)timeout); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGINT, SIG_IGN); +#ifdef HAVE_SETPRIORITY (void)setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); +#endif #ifdef OQUOTA (void)quota(Q_SETUID, 0, 0, 0); #endif @@ -351,7 +387,7 @@ main(argc, argv) (void)ioctl(0, TIOCNXCL, (char *)0); (void)fcntl(0, F_SETFL, ioctlval); #endif -#ifdef POSIX +#ifdef POSIX_TERMIOS (void)tcgetattr(0, &tc); #else (void)ioctl(0, TIOCGETP, (char *)&sgttyb); @@ -363,11 +399,12 @@ main(argc, argv) */ if (eflag) lgetstr(term, sizeof(term), "Terminal type"); -#ifdef POSIX +#ifdef POSIX_TERMIOS if (rflag || kflag || Kflag || eflag) doremoteterm(&tc); tc.c_cc[VMIN] = 1; tc.c_cc[VTIME] = 0; +#ifndef NO_INIT_CC tc.c_cc[VERASE] = CERASE; tc.c_cc[VKILL] = CKILL; tc.c_cc[VEOF] = CEOF; @@ -375,12 +412,20 @@ main(argc, argv) tc.c_cc[VQUIT] = CQUIT; tc.c_cc[VSTART] = CSTART; tc.c_cc[VSTOP] = CSTOP; +#ifndef CNUL +#define CNUL CEOL +#endif tc.c_cc[VEOL] = CNUL; /* The following are common extensions to POSIX */ #ifdef VEOL2 tc.c_cc[VEOL2] = CNUL; #endif #ifdef VSUSP +#ifdef hpux +#ifndef CSUSP +#define CSUSP CSWTCH +#endif +#endif tc.c_cc[VSUSP] = CSUSP; #endif #ifdef VDSUSP @@ -398,6 +443,7 @@ main(argc, argv) #ifdef VWERSE tc.c_cc[VWERSE] = CWERASE; #endif +#endif /* NO_INIT_CC */ tcsetattr(0, TCSANOW, &tc); #else if (rflag || kflag || Kflag || eflag) @@ -498,10 +544,14 @@ main(argc, argv) kpass_ok = 0; lpass_ok = 0; +#ifdef HAVE_SETPRIORITY (void) setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET); +#endif if (read_long_pw_string(pp2, sizeof(pp2)-1, "Password: ", 0)) { /* reading password failed... */ +#ifdef HAVE_SETPRIORITY (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); +#endif goto bad_login; } if (!pwd) /* avoid doing useless work */ @@ -550,7 +600,9 @@ main(argc, argv) realm, DEFAULT_TKT_LIFE, pp2); memset (pp2, 0, sizeof(pp2)); +#ifdef HAVE_SETPRIORITY (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); +#endif switch (krbval) { case INTK_OK: kpass_ok = 1; @@ -579,7 +631,9 @@ main(argc, argv) } } else { (void) memset (pp2, 0, sizeof(pp2)); +#ifdef HAVE_SETPRIORITY (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); +#endif } /* Policy: If local password is good, user is good. @@ -597,9 +651,13 @@ bad_login: if (krbflag) dest_tkt(); /* clean up tickets if login fails */ #else /* !KRB4 */ +#ifdef HAVE_SETPRIORITY (void) setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET); +#endif p = crypt(getpass("password:"), salt); +#ifdef HAVE_SETPRIORITY (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET); +#endif if (pwd && !strcmp(p, pwd->pw_passwd)) break; #endif /* KRB4 */ @@ -607,15 +665,25 @@ bad_login: printf("Login incorrect\n"); if (++cnt >= 5) { if (hostname) +#ifdef UT_HOSTSIZE syslog(LOG_ERR, "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s", tty, UT_HOSTSIZE, hostname, UT_NAMESIZE, username); +#else + syslog(LOG_ERR, + "REPEATED LOGIN FAILURES ON %s FROM %s, %.*s", + tty, hostname, UT_NAMESIZE, + username); +#endif else syslog(LOG_ERR, "REPEATED LOGIN FAILURES ON %s, %.*s", tty, UT_NAMESIZE, username); +/* irix has no tichpcl */ +#ifdef TIOCHPCL (void)ioctl(0, TIOCHPCL, (char *)0); +#endif sleepexit(1); } } @@ -631,8 +699,13 @@ bad_login: */ if (pwd->pw_uid == 0 && !rootterm(tty) && (passwd_req || rflag)) { if (hostname) +#ifdef UT_HOSTSIZE syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %.*s", tty, UT_HOSTSIZE, hostname); +#else + syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %s", + tty, hostname); +#endif else syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty); printf("Login incorrect\n"); @@ -672,11 +745,14 @@ bad_login: memset((char *)&utmp, 0, sizeof(utmp)); login_time = time(&utmp.ut_time); (void) strncpy(utmp.ut_name, username, sizeof(utmp.ut_name)); +#ifndef NO_UT_HOST if (hostname) (void) strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host)); else memset(utmp.ut_host, 0, sizeof(utmp.ut_host)); +#endif + /* Solaris 2.0, 2.1 used ttyn here. Never Again... */ (void) strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line)); login(&utmp); } @@ -715,6 +791,10 @@ bad_login: #ifdef OQUOTA quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); #endif +#ifdef __SCO__ + /* this is necessary when C2 mode is enabled, but not otherwise */ + setluid((uid_type) pwd->pw_uid); +#endif /* This call MUST succeed */ #ifdef _IBMR2 setuidx(ID_LOGIN, pwd->pw_uid); @@ -728,10 +808,13 @@ bad_login: pwd->pw_shell = BSHELL; /* turn on new line discipline for the csh */ else if (!strcmp(pwd->pw_shell, "/bin/csh")) { +#ifdef NTTYDISC +/* sco, svr4 don't have it */ #if !defined(_IBMR2) ioctlval = NTTYDISC; (void)ioctl(0, TIOCSETD, (char *)&ioctlval); #endif +#endif } /* destroy environment unless user has requested preservation */ @@ -771,7 +854,7 @@ bad_login: envinit[i++] = NULL; setenv("HOME", pwd->pw_dir, 0); - setenv("PATH", "/usr/local/krb5/bin:/usr/local/bin:/usr/bin/X11:/usr/ucb:/bin:/usr/bin:.", 0); + setenv("PATH", LPATH, 0); setenv("USER", pwd->pw_name, 0); setenv("SHELL", pwd->pw_shell, 0); @@ -799,16 +882,29 @@ bad_login: /* @*$&@#*($)#@$ syslog doesn't handle very many arguments */ char buf[BUFSIZ]; +#ifdef UT_HOSTSIZE (void) sprintf(buf, "ROOT LOGIN (krb) %s from %.*s, %s.%s@%s", tty, UT_HOSTSIZE, hostname, kdata->pname, kdata->pinst, kdata->prealm); +#else + (void) sprintf(buf, + "ROOT LOGIN (krb) %s from %s, %s.%s@%s", + tty, hostname, + kdata->pname, kdata->pinst, + kdata->prealm); +#endif syslog(LOG_NOTICE, buf); } else { #endif /* KRB4 */ +#ifdef UT_HOSTSIZE syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s", tty, UT_HOSTSIZE, hostname); +#else + syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %s", + tty, hostname); +#endif #ifdef KRB4 } else @@ -887,19 +983,19 @@ timedout() exit(0); } -#ifdef NOTTYENT +#ifndef HAVE_TTYENT_H int root_tty_security = 1; #endif rootterm(tty) char *tty; { -#ifdef NOTTYENT +#ifndef HAVE_TTYENT_H return(root_tty_security); #else struct ttyent *t; return((t = getttynam(tty)) && t->ty_status&TTY_SECURE); -#endif /* NOTTYENT */ +#endif /* HAVE_TTYENT_H */ } jmp_buf motdinterrupt; @@ -942,7 +1038,7 @@ dolastlog(quiet, tty) int quiet; char *tty; { -#if !defined(_AIX) +#ifdef HAVE_LASTLOG_H struct lastlog ll; int fd; @@ -981,7 +1077,7 @@ char * stypeof(ttyid) char *ttyid; { -#ifdef NOTTYENT +#ifndef HAVE_TTYENT_H return(UNKNOWN); #else struct ttyent *t; @@ -1126,8 +1222,18 @@ char *speeds[] = { }; #define NSPEEDS (sizeof(speeds) / sizeof(speeds[0])) +#ifdef POSIX_TERMIOS +#ifndef CBAUD +/* this must be in sync with the list above */ +speed_t b_speeds[] = { + B0, B50, B75, B110, B134, B150, B200, B300, B600, + B1200, B1800, B2400, B4800, B9600, B19200, B38400, +}; +#endif +#endif + doremoteterm(tp) -#ifdef POSIX +#ifdef POSIX_TERMIOS struct termios *tp; #else struct sgttyb *tp; @@ -1144,21 +1250,38 @@ doremoteterm(tp) *cp++ = '\0'; for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) if (strcmp(*cpp, speed) == 0) { -#ifdef POSIX +#ifdef POSIX_TERMIOS +#ifdef CBAUD +/* some otherwise-posix systems seem not to have cfset... for now, leave + the old code for those who can use it */ tp->c_cflag = (tp->c_cflag & ~CBAUD) | (cpp-speeds); #else + cfsetispeed(tp, b_speeds[cpp-speeds]); + cfsetospeed(tp, b_speeds[cpp-speeds]); +#endif +#else tp->sg_ispeed = tp->sg_ospeed = cpp-speeds; #endif break; } } -#ifdef POSIX +#ifdef POSIX_TERMIOS /* set all standard echo, edit, and job control options */ - tp->c_lflag = ECHO|ECHOE|ECHOK|ICANON|ISIG; + /* but leave any extensions */ + tp->c_lflag |= ECHO|ECHOE|ECHOK|ICANON|ISIG; + tp->c_lflag &= ~(NOFLSH|TOSTOP|IEXTEN); +#ifdef ECHOCTL + /* Not POSIX, but if we have it, we probably want it */ + tp->c_lflag |= ECHOCTL; +#endif +#ifdef ECHOKE + /* Not POSIX, but if we have it, we probably want it */ + tp->c_lflag |= ECHOKE; +#endif tp->c_iflag |= ICRNL|BRKINT; tp->c_oflag |= ONLCR|OPOST|TAB3; -#else /* !POSIX */ +#else /* !POSIX_TERMIOS */ tp->sg_flags = ECHO|CRMOD|ANYP|XTABS; #endif } @@ -1180,6 +1303,11 @@ sleepexit(eval) * It exits only in the child process. */ #include <sys/wait.h> +#ifdef WAIT_USES_INT +#define WAIT_TYPE int +#else +#define WAIT_TYPE union wait +#endif void dofork() { @@ -1195,7 +1323,7 @@ dofork() (void) chdir("/"); /* Let's not keep the fs busy... */ /* If we're the parent, watch the child until it dies */ - while(wait((union wait *)0) != child) + while(wait((WAIT_TYPE *)0) != child) ; /* Cleanup stuff */ @@ -1215,14 +1343,6 @@ dofork() #endif /* KRB4 */ -char *strsave(s) -char *s; -{ - char *ret = (char *)malloc(strlen(s) + 1); - strcpy(ret, s); - return(ret); -} - #ifdef _IBMR2 update_ref_count(int adj) { |