1*2111Swnj static char *sccsid = "@(#)login.c 4.9 (Berkeley) 01/11/81"; 21043Sbill /* 31043Sbill * login [ name ] 41043Sbill */ 51043Sbill 61043Sbill #include <sys/types.h> 71043Sbill #include <sgtty.h> 81043Sbill #include <utmp.h> 91043Sbill #include <signal.h> 101043Sbill #include <pwd.h> 111043Sbill #include <stdio.h> 121043Sbill #include <sys/stat.h> 131043Sbill #include <lastlog.h> 141804Sbill #include <whoami.h> 151043Sbill #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 161043Sbill 171043Sbill #define NMAX sizeof(utmp.ut_name) 181043Sbill #define LMAX sizeof(utmp.ut_line) 191043Sbill 201043Sbill char user[20]; 211043Sbill char maildir[30] = "/usr/spool/mail/"; 221043Sbill char lastlog[] = "/usr/adm/lastlog"; 231043Sbill struct passwd nouser = {"", "nope"}; 241043Sbill struct sgttyb ttyb; 251043Sbill struct utmp utmp; 261043Sbill char minusnam[16] = "-"; 271043Sbill char homedir[64] = "HOME="; 281043Sbill char shell[64] = "SHELL="; 291043Sbill char term[64] = "TERM="; 301043Sbill char *envinit[] = {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", term, user,0}; 311043Sbill struct passwd *pwd; 321043Sbill 331043Sbill struct passwd *getpwnam(); 341043Sbill char *strcat(); 351043Sbill int setpwent(); 361043Sbill char *ttyname(); 371043Sbill char *crypt(); 381043Sbill char *getpass(); 391043Sbill char *rindex(); 401043Sbill char *stypeof(); 411043Sbill extern char **environ; 421043Sbill 431365Sbill #define CTRL(c) ('c'&037) 441365Sbill #define CERASE '#' 451365Sbill #define CEOT CTRL(d) 461365Sbill #define CKILL '@' 471365Sbill #define CQUIT 034 /* FS, cntl shift L */ 481365Sbill #define CINTR 0177 /* DEL */ 491365Sbill #define CSTOP CTRL(s) 501365Sbill #define CSTART CTRL(q) 511365Sbill #define CBRK 0377 521365Sbill struct tchars tc = { 531365Sbill CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK 541365Sbill }; 551365Sbill struct ltchars ltc = { 561546Sbill CTRL(z), CTRL(y), CTRL(r), CTRL(o), CTRL(w), CTRL(v) 571365Sbill }; 581365Sbill 591043Sbill main(argc, argv) 601043Sbill char **argv; 611043Sbill { 621043Sbill register char *namep; 631043Sbill int t, f, c; 641043Sbill char *ttyn; 651043Sbill int ldisc = 0; 661043Sbill 671043Sbill alarm(60); 681043Sbill signal(SIGQUIT, SIG_IGN); 691043Sbill signal(SIGINT, SIG_IGN); 701043Sbill nice(-100); 711043Sbill nice(20); 721043Sbill nice(0); 731043Sbill ioctl(0, TIOCLSET, 0); 741547Sbill ioctl(0, TIOCNXCL, 0); 751043Sbill gtty(0, &ttyb); 761043Sbill ttyb.sg_erase = '#'; 771043Sbill ttyb.sg_kill = '@'; 781043Sbill stty(0, &ttyb); 791365Sbill ioctl(0, TIOCSETC, &tc); 801365Sbill ioctl(0, TIOCSLTC, <c); 811043Sbill for (t=3; t<20; t++) 821043Sbill close(t); 831043Sbill ttyn = ttyname(0); 841043Sbill if (ttyn==0) 851043Sbill ttyn = "/dev/tty??"; 861043Sbill 871043Sbill loop: 881547Sbill ldisc = 0; 891547Sbill ioctl(0, TIOCSETD, &ldisc); 901043Sbill SCPYN(utmp.ut_name, ""); 911043Sbill if (argc>1) { 921043Sbill SCPYN(utmp.ut_name, argv[1]); 931043Sbill argc = 0; 941043Sbill } 951043Sbill while (utmp.ut_name[0] == '\0') { 961043Sbill namep = utmp.ut_name; 971043Sbill printf("login: "); 981043Sbill while ((c = getchar()) != '\n') { 991043Sbill if(c == ' ') 1001043Sbill c = '_'; 1011043Sbill if (c == EOF) 1021043Sbill exit(0); 1031043Sbill if (namep < utmp.ut_name+NMAX) 1041043Sbill *namep++ = c; 1051043Sbill } 1061043Sbill } 1071043Sbill setpwent(); 1081043Sbill if ((pwd = getpwnam(utmp.ut_name)) == NULL) 1091043Sbill pwd = &nouser; 1101043Sbill endpwent(); 1111547Sbill if (!strcmp(pwd->pw_shell, "/bin/csh")) { 1121547Sbill ldisc = NTTYDISC; 1131547Sbill ioctl(0, TIOCSETD, &ldisc); 1141547Sbill } 1151043Sbill if (*pwd->pw_passwd != '\0') { 1161547Sbill nice(-4); 1171043Sbill namep = crypt(getpass("Password:"),pwd->pw_passwd); 1181547Sbill nice(4); 1191043Sbill if (strcmp(namep, pwd->pw_passwd)) { 1201043Sbill bad: 1211043Sbill printf("Login incorrect\n"); 1221043Sbill if (ttyn[LMAX] == 'd') { 1231043Sbill FILE *console = fopen("/dev/console", "w"); 1241043Sbill if (console != NULL) { 1251043Sbill fprintf(console, "\r\nBADDIALUP %s %s\r\n", ttyn+5, utmp.ut_name); 1261043Sbill fclose(console); 1271043Sbill } 1281043Sbill } 1291043Sbill goto loop; 1301043Sbill } 1311043Sbill } 1321043Sbill sprintf(user, "USER=%.*s", NMAX, pwd->pw_name); 1331804Sbill #ifdef ERNIE 1341043Sbill if (pwd->pw_uid == 0 && ttyn[5] != 'c') 1351043Sbill goto bad; 1361804Sbill #endif 1371043Sbill if (ttyn[LMAX] == 'd') { 1381043Sbill FILE *console = fopen("/dev/console", "w"); 1391043Sbill if (console != NULL) { 1401043Sbill fprintf(console, "\r\nDIALUP %s %s\r\n", ttyn+5, pwd->pw_name); 1411043Sbill fclose(console); 1421043Sbill } 1431043Sbill } 1441043Sbill if((f = open(lastlog, 2)) >= 0) { 1451043Sbill struct lastlog ll; 1461043Sbill 1471601Smark lseek(f, (long) pwd->pw_uid * sizeof (struct lastlog), 0); 1481043Sbill if (read(f, (char *) &ll, sizeof ll) == sizeof ll && ll.ll_time != 0) { 1491043Sbill register char *ep = (char *) ctime(&ll.ll_time); 1501043Sbill printf("Last login: "); 1511043Sbill ep[24 - 5] = 0; 1521043Sbill printf("%s on %.*s\n", ep, LMAX, ll.ll_line); 1531043Sbill } 1541601Smark lseek(f, (long) pwd->pw_uid * sizeof (struct lastlog), 0); 1551043Sbill time(&ll.ll_time); 1561043Sbill strcpyn(ll.ll_line, ttyn+5, LMAX); 1571043Sbill write(f, (char *) &ll, sizeof ll); 1581043Sbill close(f); 1591043Sbill } 1601043Sbill if(chdir(pwd->pw_dir) < 0) { 1612106Sroot printf("Logging with home=/\n"); 1622106Sroot pwd->pw_dir = "/"; 1632106Sroot if(chdir("/") < 0) { 1641043Sbill printf("No directory\n"); 1651043Sbill goto loop; 1661882Sbill } 1671043Sbill } 1681043Sbill time(&utmp.ut_time); 1691043Sbill t = ttyslot(); 1701043Sbill if (t>0 && (f = open("/etc/utmp", 1)) >= 0) { 1711043Sbill lseek(f, (long)(t*sizeof(utmp)), 0); 1721043Sbill SCPYN(utmp.ut_line, rindex(ttyn, '/')+1); 1731043Sbill write(f, (char *)&utmp, sizeof(utmp)); 1741043Sbill close(f); 1751043Sbill } 1761043Sbill if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) { 1771043Sbill lseek(f, 0L, 2); 1781043Sbill write(f, (char *)&utmp, sizeof(utmp)); 1791043Sbill close(f); 1801043Sbill } 1811043Sbill chown(ttyn, pwd->pw_uid, pwd->pw_gid); 1821043Sbill setgid(pwd->pw_gid); 1831043Sbill setuid(pwd->pw_uid); 1841043Sbill if (*pwd->pw_shell == '\0') 1851043Sbill pwd->pw_shell = "/bin/sh"; 1861043Sbill environ = envinit; 1871043Sbill strncat(homedir, pwd->pw_dir, sizeof(homedir)-6); 1881043Sbill strncat(shell, pwd->pw_shell, sizeof(shell)-7); 1891043Sbill strncat(term, stypeof(ttyn), sizeof(term)-6); 1901043Sbill if ((namep = rindex(pwd->pw_shell, '/')) == NULL) 1911043Sbill namep = pwd->pw_shell; 1921043Sbill else 1931043Sbill namep++; 1941043Sbill strcat(minusnam, namep); 1951043Sbill alarm(0); 196*2111Swnj #ifdef ARPAVAX 197*2111Swnj if (pwd->pw_gid == 31) 198*2111Swnj umask(2); 199*2111Swnj else 200*2111Swnj #else 201*2111Swnj umask(022); 202*2111Swnj #endif 2031043Sbill showmotd(); 2041043Sbill strcat(maildir, pwd->pw_name); 2051043Sbill if(access(maildir,4)==0) { 2061043Sbill struct stat statb; 2071043Sbill stat(maildir, &statb); 2081043Sbill if (statb.st_size) 2091043Sbill printf("You have mail.\n"); 2101043Sbill } 2111043Sbill signal(SIGQUIT, SIG_DFL); 2121043Sbill signal(SIGINT, SIG_DFL); 2131043Sbill execlp(pwd->pw_shell, minusnam, 0); 2141043Sbill printf("No shell\n"); 2151043Sbill exit(0); 2161043Sbill } 2171043Sbill 2181043Sbill int stopmotd; 2191043Sbill catch() 2201043Sbill { 2211043Sbill signal(SIGINT, SIG_IGN); 2221043Sbill stopmotd++; 2231043Sbill } 2241043Sbill 2251043Sbill showmotd() 2261043Sbill { 2271043Sbill FILE *mf; 2281043Sbill register c; 2291043Sbill 2301043Sbill signal(SIGINT, catch); 2311043Sbill if((mf = fopen("/etc/motd","r")) != NULL) { 2321043Sbill while((c = getc(mf)) != EOF && stopmotd == 0) 2331043Sbill putchar(c); 2341043Sbill fclose(mf); 2351043Sbill } 2361043Sbill signal(SIGINT, SIG_IGN); 2371043Sbill } 2381043Sbill 2391043Sbill #define UNKNOWN "su" 2401043Sbill 2411043Sbill char * 2421043Sbill stypeof(ttyid) 2431043Sbill char *ttyid; 2441043Sbill { 2451043Sbill static char typebuf[16]; 2461043Sbill char buf[50]; 2471043Sbill register FILE *f; 2481043Sbill register char *p, *t, *q; 2491043Sbill 2501043Sbill if (ttyid == NULL) 2511043Sbill return (UNKNOWN); 2521043Sbill f = fopen("/etc/ttytype", "r"); 2531043Sbill if (f == NULL) 2541043Sbill return (UNKNOWN); 2551043Sbill /* split off end of name */ 2561043Sbill for (p = q = ttyid; *p != 0; p++) 2571043Sbill if (*p == '/') 2581043Sbill q = p + 1; 2591043Sbill 2601043Sbill /* scan the file */ 2611043Sbill while (fgets(buf, sizeof buf, f) != NULL) 2621043Sbill { 2631043Sbill for (t=buf; *t!=' '; t++) 2641043Sbill ; 2651043Sbill *t++ = 0; 2661043Sbill for (p=t; *p>' '; p++) 2671043Sbill ; 2681043Sbill *p = 0; 2691043Sbill if (strcmp(q,t)==0) { 2701043Sbill strcpy(typebuf, buf); 2711043Sbill fclose(f); 2721043Sbill return (typebuf); 2731043Sbill } 2741043Sbill } 2751043Sbill fclose (f); 2761043Sbill return (UNKNOWN); 2771043Sbill } 278