X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/6f01c4263ca6afdb8b38c10554a3bc5ae6029dbc..b43898148f3c1083924576f519159bf823402512:/usr/src/usr.bin/login/login.c diff --git a/usr/src/usr.bin/login/login.c b/usr/src/usr.bin/login/login.c index ed8ccf3256..8f738f0588 100644 --- a/usr/src/usr.bin/login/login.c +++ b/usr/src/usr.bin/login/login.c @@ -1,6 +1,8 @@ -static char *sccsid = "@(#)login.c 4.9 (Berkeley) %G%"; +static char *sccsid = "@(#)login.c 4.14 82/03/15"; /* * login [ name ] + * login -r + * login -r [ rhost ] */ #include @@ -11,27 +13,40 @@ static char *sccsid = "@(#)login.c 4.9 (Berkeley) %G%"; #include #include #include -#include -#define SCPYN(a, b) strncpy(a, b, sizeof(a)) -#define NMAX sizeof(utmp.ut_name) -#define LMAX sizeof(utmp.ut_line) +#define SCPYN(a, b) strncpy(a, b, sizeof(a)) -char user[20]; +#define NMAX sizeof(utmp.ut_name) +#define LMAX sizeof(utmp.ut_line) + +#define FALSE 0 +#define TRUE -1 + +char nolog[] = "/etc/nologin"; +char qlog[] = ".hushlogin"; +char securetty[] = "/etc/securetty"; char maildir[30] = "/usr/spool/mail/"; char lastlog[] = "/usr/adm/lastlog"; struct passwd nouser = {"", "nope"}; struct sgttyb ttyb; struct utmp utmp; char minusnam[16] = "-"; + char homedir[64] = "HOME="; char shell[64] = "SHELL="; char term[64] = "TERM="; -char *envinit[] = {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", term, user,0}; -struct passwd *pwd; +char user[20] = "USER="; +char *speeds[] = + { "0", "50", "75", "110", "134", "150", "200", "300", + "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" }; +#define NSPEEDS (sizeof (speeds) / sizeof (speeds[0])) + +char *envinit[] = + {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", term, user, 0}; +struct passwd *pwd; struct passwd *getpwnam(); -char *strcat(); +char *strcat(), *rindex(), *index(); int setpwent(); char *ttyname(); char *crypt(); @@ -56,13 +71,23 @@ struct ltchars ltc = { CTRL(z), CTRL(y), CTRL(r), CTRL(o), CTRL(w), CTRL(v) }; +int rflag; +char rusername[NMAX+1], lusername[NMAX+1]; +char rpassword[NMAX+1]; +char *rhost; + main(argc, argv) char **argv; { register char *namep; int t, f, c; + int invalid; + int quietlog; + int i; + FILE *nlfd; char *ttyn; - int ldisc = 0; + int ldisc = 0, zero = 0; + FILE *hostf; int first = 1; alarm(60); signal(SIGQUIT, SIG_IGN); @@ -70,101 +95,186 @@ char **argv; nice(-100); nice(20); nice(0); - ioctl(0, TIOCLSET, 0); + if (argc > 0 && !strcmp(argv[1], "-r")) { + rflag++; + if (argc > 1) + rhost = argv[2]; + argc = 1; + if (rhost) { + getstr(rusername, sizeof (rusername), "remuser"); + getstr(lusername, sizeof (lusername), "locuser"); + } else { + getstr(lusername, sizeof (lusername), "Username"); + getstr(rpassword, sizeof (rpassword), "Password"); + } + getstr(term+5, sizeof(term)-5, "Terminal type"); + if (rhost == 0) + goto normal; + if (getuid()) { + rflag = 0; + goto normal; + } + setpwent(); + pwd = getpwnam(lusername); + if (pwd == NULL) { + fprintf(stderr, "Login incorrect.\n"); + exit(1); + } + endpwent(); + hostf = fopen("/etc/hosts.equiv", "r"); + again: + if (hostf) { + char ahost[32]; + while (fgets(ahost, sizeof (ahost), hostf)) { + char *user; + if (index(ahost, '\n')) + *index(ahost, '\n') = 0; + user = index(ahost, ' '); + if (user) + *user++ = 0; + if (!strcmp(rhost, ahost) && + !strcmp(rusername, user ? user : lusername)) + goto normal; + } + fclose(hostf); + } + if (first == 1) { + first = 0; + if (chdir(pwd->pw_dir) < 0) + goto again; + hostf = fopen(".rhosts", "r"); + goto again; + } + rhost = 0; + rflag = -1; + } +normal: + ioctl(0, TIOCLSET, &zero); ioctl(0, TIOCNXCL, 0); gtty(0, &ttyb); - ttyb.sg_erase = '#'; - ttyb.sg_kill = '@'; + if (rflag) { + char *cp = index(term, '/'); + if (cp) { + int i; + *cp++ = 0; + for (i = 0; i < NSPEEDS; i++) + if (!strcmp(speeds[i], cp)) { + ttyb.sg_ispeed = ttyb.sg_ospeed = i; + break; + } + } + ttyb.sg_flags = ECHO|CRMOD|ANYP|XTABS; + } + if (rflag == -1) + rflag = 0; + ttyb.sg_erase = CERASE; + ttyb.sg_kill = CKILL; stty(0, &ttyb); ioctl(0, TIOCSETC, &tc); ioctl(0, TIOCSLTC, <c); for (t=3; t<20; t++) close(t); ttyn = ttyname(0); - if (ttyn==0) + if (ttyn==(char *)0) ttyn = "/dev/tty??"; - - loop: - ldisc = 0; - ioctl(0, TIOCSETD, &ldisc); - SCPYN(utmp.ut_name, ""); - if (argc>1) { - SCPYN(utmp.ut_name, argv[1]); - argc = 0; - } - while (utmp.ut_name[0] == '\0') { - namep = utmp.ut_name; - printf("login: "); - while ((c = getchar()) != '\n') { - if(c == ' ') - c = '_'; - if (c == EOF) - exit(0); - if (namep < utmp.ut_name+NMAX) - *namep++ = c; - } - } - setpwent(); - if ((pwd = getpwnam(utmp.ut_name)) == NULL) - pwd = &nouser; - endpwent(); - if (!strcmp(pwd->pw_shell, "/bin/csh")) { - ldisc = NTTYDISC; + do { + ldisc = 0; ioctl(0, TIOCSETD, &ldisc); - } - if (*pwd->pw_passwd != '\0') { - nice(-4); - namep = crypt(getpass("Password:"),pwd->pw_passwd); - nice(4); - if (strcmp(namep, pwd->pw_passwd)) { -bad: + invalid = FALSE; + SCPYN(utmp.ut_name, ""); + if (argc>1) { + SCPYN(utmp.ut_name, argv[1]); + argc = 0; + } + if (rflag) + strcpy(utmp.ut_name, lusername); + else + while (utmp.ut_name[0] == '\0') { + namep = utmp.ut_name; + { char hostname[32]; + gethostname(hostname, sizeof (hostname)); + printf("%s login: ", hostname); } + while ((c = getchar()) != '\n') { + if (c == ' ') + c = '_'; + if (c == EOF) + exit(0); + if (namep < utmp.ut_name+NMAX) + *namep++ = c; + } + } + if (rhost == 0) { + setpwent(); + if ((pwd = getpwnam(utmp.ut_name)) == NULL) + pwd = &nouser; + endpwent(); + } + if (!strcmp(pwd->pw_shell, "/bin/csh")) { + ldisc = NTTYDISC; + ioctl(0, TIOCSETD, &ldisc); + } + if (rhost == 0) { + if (*pwd->pw_passwd != '\0') { + char *pp; + nice(-4); + if (rflag == 0) + pp = getpass("Password:"); + else + pp = rpassword; + namep = crypt(pp,pwd->pw_passwd); + nice(4); + if (strcmp(namep, pwd->pw_passwd)) + invalid = TRUE; + } + } + if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) { + /* logins are disabled except for root */ + while ((c = getc(nlfd)) != EOF) + putchar(c); + fflush(stdout); + sleep(5); + exit(0); + } + if (!invalid && pwd->pw_uid == 0 && + !rootterm(ttyn+sizeof("/dev/")-1)) { + FILE *console = fopen("/dev/console", "w"); + if (console != NULL) { + fprintf(console, "\r\nROOT LOGIN REFUSED %s\r\n" + , ttyn+sizeof("/dev/")-1 + ); + fclose(console); + } + invalid = TRUE; + } + if (invalid) { printf("Login incorrect\n"); - if (ttyn[LMAX] == 'd') { + if (ttyn[sizeof("/dev/tty")-1] == 'd') { FILE *console = fopen("/dev/console", "w"); if (console != NULL) { - fprintf(console, "\r\nBADDIALUP %s %s\r\n", ttyn+5, utmp.ut_name); + fprintf(console, "\r\nBADDIALUP %s %s\r\n" + , ttyn+sizeof("/dev/")-1 + , utmp.ut_name); fclose(console); } } - goto loop; } - } - sprintf(user, "USER=%.*s", NMAX, pwd->pw_name); -#ifdef ERNIE - if (pwd->pw_uid == 0 && ttyn[5] != 'c') - goto bad; -#endif - if (ttyn[LMAX] == 'd') { - FILE *console = fopen("/dev/console", "w"); - if (console != NULL) { - fprintf(console, "\r\nDIALUP %s %s\r\n", ttyn+5, pwd->pw_name); - fclose(console); + if (*pwd->pw_shell == '\0') + pwd->pw_shell = "/bin/sh"; + i = strlen(pwd->pw_shell); + if (chdir(pwd->pw_dir) < 0 && !invalid ) { + if (chdir("/") < 0) { + printf("No directory!\n"); + invalid = TRUE; + } else { + printf("No directory! Logging in with home=/\n"); + pwd->pw_dir = "/"; + } } - } - if((f = open(lastlog, 2)) >= 0) { - struct lastlog ll; + if (rflag && invalid) + exit(1); + } while (invalid); + - lseek(f, (long) pwd->pw_uid * sizeof (struct lastlog), 0); - if (read(f, (char *) &ll, sizeof ll) == sizeof ll && ll.ll_time != 0) { - register char *ep = (char *) ctime(&ll.ll_time); - printf("Last login: "); - ep[24 - 5] = 0; - printf("%s on %.*s\n", ep, LMAX, ll.ll_line); - } - lseek(f, (long) pwd->pw_uid * sizeof (struct lastlog), 0); - time(&ll.ll_time); - strcpyn(ll.ll_line, ttyn+5, LMAX); - write(f, (char *) &ll, sizeof ll); - close(f); - } - if(chdir(pwd->pw_dir) < 0) { - printf("Logging with home=/\n"); - pwd->pw_dir = "/"; - if(chdir("/") < 0) { - printf("No directory\n"); - goto loop; - } - } time(&utmp.ut_time); t = ttyslot(); if (t>0 && (f = open("/etc/utmp", 1)) >= 0) { @@ -178,39 +288,71 @@ bad: write(f, (char *)&utmp, sizeof(utmp)); close(f); } + quietlog = FALSE; + if (access(qlog, 0) == 0) + quietlog = TRUE; + if ( !quietlog && (f = open(lastlog, 2)) >= 0 ) { + struct lastlog ll; + + lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); + if (read(f, (char *) &ll, sizeof ll) == sizeof ll && + ll.ll_time != 0) { + printf("Last login: %.*s on %.*s\n" + , 24-5 + , (char *) ctime(&ll.ll_time) + , sizeof(ll.ll_line) + , ll.ll_line + ); + } + lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); + time(&ll.ll_time); + SCPYN(ll.ll_line, rindex(ttyn, '/')+1); + write(f, (char *) &ll, sizeof ll); + close(f); + } chown(ttyn, pwd->pw_uid, pwd->pw_gid); setgid(pwd->pw_gid); + inigrp(utmp.ut_name, pwd->pw_gid); setuid(pwd->pw_uid); - if (*pwd->pw_shell == '\0') - pwd->pw_shell = "/bin/sh"; environ = envinit; strncat(homedir, pwd->pw_dir, sizeof(homedir)-6); strncat(shell, pwd->pw_shell, sizeof(shell)-7); - strncat(term, stypeof(ttyn), sizeof(term)-6); + if (rflag == 0) + strncat(term, stypeof(ttyn), sizeof(term)-6); + strncat(user, pwd->pw_name, sizeof(user)-6); if ((namep = rindex(pwd->pw_shell, '/')) == NULL) namep = pwd->pw_shell; else namep++; strcat(minusnam, namep); alarm(0); -#ifdef ARPAVAX - if (pwd->pw_gid == 31) - umask(2); - else -#else - umask(022); -#endif - showmotd(); - strcat(maildir, pwd->pw_name); - if(access(maildir,4)==0) { - struct stat statb; - stat(maildir, &statb); - if (statb.st_size) - printf("You have mail.\n"); + umask(022); + if (ttyn[sizeof("/dev/tty")-1] == 'd') { + FILE *console = fopen("/dev/console", "w"); + if (console != NULL) { + fprintf(console, "\r\nDIALUP %s %s\r\n" + , ttyn+sizeof("/dev/")-1 + , pwd->pw_name + ); + fclose(console); + } + } + if ( !quietlog ) { + showmotd(); + strcat(maildir, pwd->pw_name); + if (access(maildir,4)==0) { + struct stat statb; + stat(maildir, &statb); + if (statb.st_size) + printf("You have mail.\n"); + } } + signal(SIGQUIT, SIG_DFL); signal(SIGINT, SIG_DFL); + signal(SIGTSTP, SIG_IGN); execlp(pwd->pw_shell, minusnam, 0); + perror(pwd->pw_shell); printf("No shell\n"); exit(0); } @@ -222,20 +364,43 @@ catch() stopmotd++; } +/* + * return true if OK for root to login on this terminal + */ +rootterm(tty) + char *tty; +{ + register FILE *fd; + char buf[100]; + + if ((fd = fopen(securetty, "r")) == NULL) + return(1); + while (fgets(buf, sizeof buf, fd) != NULL) { + buf[strlen(buf)-1] = '\0'; + if (strcmp(tty, buf) == 0) { + fclose(fd); + return(1); + } + } + fclose(fd); + return(0); +} + showmotd() { FILE *mf; register c; signal(SIGINT, catch); - if((mf = fopen("/etc/motd","r")) != NULL) { - while((c = getc(mf)) != EOF && stopmotd == 0) + if ((mf = fopen("/etc/motd","r")) != NULL) { + while ((c = getc(mf)) != EOF && stopmotd == 0) putchar(c); fclose(mf); } signal(SIGINT, SIG_IGN); } +#undef UNKNOWN #define UNKNOWN "su" char * @@ -260,9 +425,11 @@ char *ttyid; /* scan the file */ while (fgets(buf, sizeof buf, f) != NULL) { - for (t=buf; *t!=' '; t++) + for (t=buf; *t!=' ' && *t != '\t'; t++) ; *t++ = 0; + while (*t == ' ' || *t == '\t') + t++; for (p=t; *p>' '; p++) ; *p = 0; @@ -275,3 +442,21 @@ char *ttyid; fclose (f); return (UNKNOWN); } + +getstr(buf, cnt, err) + char *buf; + int cnt; + char *err; +{ + char c; + + do { + if (read(0, &c, 1) != 1) + exit(1); + if (--cnt < 0) { + printf("%s too long\r\n", err); + exit(1); + } + *buf++ = c; + } while (c != 0); +}