1*1546Sbill static char *sccsid = "@(#)login.c 4.3 (Berkeley) 10/19/80"; 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> 141043Sbill #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 151043Sbill 161043Sbill #define NMAX sizeof(utmp.ut_name) 171043Sbill #define LMAX sizeof(utmp.ut_line) 181043Sbill 191043Sbill char user[20]; 201043Sbill char maildir[30] = "/usr/spool/mail/"; 211043Sbill char lastlog[] = "/usr/adm/lastlog"; 221043Sbill struct passwd nouser = {"", "nope"}; 231043Sbill struct sgttyb ttyb; 241043Sbill struct utmp utmp; 251043Sbill char minusnam[16] = "-"; 261043Sbill char homedir[64] = "HOME="; 271043Sbill char shell[64] = "SHELL="; 281043Sbill char term[64] = "TERM="; 291043Sbill char *envinit[] = {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", term, user,0}; 301043Sbill struct passwd *pwd; 311043Sbill 321043Sbill struct passwd *getpwnam(); 331043Sbill char *strcat(); 341043Sbill int setpwent(); 351043Sbill char *ttyname(); 361043Sbill char *crypt(); 371043Sbill char *getpass(); 381043Sbill char *rindex(); 391043Sbill char *stypeof(); 401043Sbill extern char **environ; 411043Sbill 421365Sbill #define CTRL(c) ('c'&037) 431365Sbill #define CERASE '#' 441365Sbill #define CEOT CTRL(d) 451365Sbill #define CKILL '@' 461365Sbill #define CQUIT 034 /* FS, cntl shift L */ 471365Sbill #define CINTR 0177 /* DEL */ 481365Sbill #define CSTOP CTRL(s) 491365Sbill #define CSTART CTRL(q) 501365Sbill #define CBRK 0377 511365Sbill struct tchars tc = { 521365Sbill CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK 531365Sbill }; 541365Sbill struct ltchars ltc = { 55*1546Sbill CTRL(z), CTRL(y), CTRL(r), CTRL(o), CTRL(w), CTRL(v) 561365Sbill }; 571365Sbill 581043Sbill main(argc, argv) 591043Sbill char **argv; 601043Sbill { 611043Sbill register char *namep; 621043Sbill int t, f, c; 631043Sbill char *ttyn; 641043Sbill int ldisc = 0; 651043Sbill 661043Sbill alarm(60); 671043Sbill signal(SIGQUIT, SIG_IGN); 681043Sbill signal(SIGINT, SIG_IGN); 691043Sbill nice(-100); 701043Sbill nice(20); 711043Sbill nice(0); 721365Sbill ioctl(0, TIOCSETD, &ldisc); 731043Sbill ioctl(0, TIOCLSET, 0); 741043Sbill gtty(0, &ttyb); 751043Sbill ttyb.sg_erase = '#'; 761043Sbill ttyb.sg_kill = '@'; 771043Sbill stty(0, &ttyb); 781365Sbill ioctl(0, TIOCSETC, &tc); 791365Sbill ioctl(0, TIOCSLTC, <c); 801043Sbill for (t=3; t<20; t++) 811043Sbill close(t); 821043Sbill ttyn = ttyname(0); 831043Sbill if (ttyn==0) 841043Sbill ttyn = "/dev/tty??"; 851043Sbill 861043Sbill loop: 871043Sbill SCPYN(utmp.ut_name, ""); 881043Sbill if (argc>1) { 891043Sbill SCPYN(utmp.ut_name, argv[1]); 901043Sbill argc = 0; 911043Sbill } 921043Sbill while (utmp.ut_name[0] == '\0') { 931043Sbill namep = utmp.ut_name; 941043Sbill printf("login: "); 951043Sbill while ((c = getchar()) != '\n') { 961043Sbill if(c == ' ') 971043Sbill c = '_'; 981043Sbill if (c == EOF) 991043Sbill exit(0); 1001043Sbill if (namep < utmp.ut_name+NMAX) 1011043Sbill *namep++ = c; 1021043Sbill } 1031043Sbill } 1041043Sbill setpwent(); 1051043Sbill if ((pwd = getpwnam(utmp.ut_name)) == NULL) 1061043Sbill pwd = &nouser; 1071043Sbill endpwent(); 1081043Sbill if (*pwd->pw_passwd != '\0') { 1091043Sbill namep = crypt(getpass("Password:"),pwd->pw_passwd); 1101043Sbill if (strcmp(namep, pwd->pw_passwd)) { 1111043Sbill bad: 1121043Sbill printf("Login incorrect\n"); 1131043Sbill if (ttyn[LMAX] == 'd') { 1141043Sbill FILE *console = fopen("/dev/console", "w"); 1151043Sbill if (console != NULL) { 1161043Sbill fprintf(console, "\r\nBADDIALUP %s %s\r\n", ttyn+5, utmp.ut_name); 1171043Sbill fclose(console); 1181043Sbill } 1191043Sbill } 1201043Sbill goto loop; 1211043Sbill } 1221043Sbill } 1231043Sbill sprintf(user, "USER=%.*s", NMAX, pwd->pw_name); 1241043Sbill if (pwd->pw_uid == 0 && ttyn[5] != 'c') 1251043Sbill goto bad; 1261043Sbill if (ttyn[LMAX] == 'd') { 1271043Sbill FILE *console = fopen("/dev/console", "w"); 1281043Sbill if (console != NULL) { 1291043Sbill fprintf(console, "\r\nDIALUP %s %s\r\n", ttyn+5, pwd->pw_name); 1301043Sbill fclose(console); 1311043Sbill } 1321043Sbill } 1331043Sbill if((f = open(lastlog, 2)) >= 0) { 1341043Sbill struct lastlog ll; 1351043Sbill 1361043Sbill lseek(f, pwd->pw_uid * sizeof (struct lastlog), 0); 1371043Sbill if (read(f, (char *) &ll, sizeof ll) == sizeof ll && ll.ll_time != 0) { 1381043Sbill register char *ep = (char *) ctime(&ll.ll_time); 1391043Sbill printf("Last login: "); 1401043Sbill ep[24 - 5] = 0; 1411043Sbill printf("%s on %.*s\n", ep, LMAX, ll.ll_line); 1421043Sbill } 1431043Sbill lseek(f, pwd->pw_uid * sizeof (struct lastlog), 0); 1441043Sbill time(&ll.ll_time); 1451043Sbill strcpyn(ll.ll_line, ttyn+5, LMAX); 1461043Sbill write(f, (char *) &ll, sizeof ll); 1471043Sbill close(f); 1481043Sbill } 1491043Sbill if(chdir(pwd->pw_dir) < 0) { 1501043Sbill printf("No directory\n"); 1511043Sbill goto loop; 1521043Sbill } 1531043Sbill time(&utmp.ut_time); 1541043Sbill t = ttyslot(); 1551043Sbill if (t>0 && (f = open("/etc/utmp", 1)) >= 0) { 1561043Sbill lseek(f, (long)(t*sizeof(utmp)), 0); 1571043Sbill SCPYN(utmp.ut_line, rindex(ttyn, '/')+1); 1581043Sbill write(f, (char *)&utmp, sizeof(utmp)); 1591043Sbill close(f); 1601043Sbill } 1611043Sbill if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) { 1621043Sbill lseek(f, 0L, 2); 1631043Sbill write(f, (char *)&utmp, sizeof(utmp)); 1641043Sbill close(f); 1651043Sbill } 1661043Sbill chown(ttyn, pwd->pw_uid, pwd->pw_gid); 1671043Sbill setgid(pwd->pw_gid); 1681043Sbill setuid(pwd->pw_uid); 1691043Sbill if (*pwd->pw_shell == '\0') 1701043Sbill pwd->pw_shell = "/bin/sh"; 1711043Sbill environ = envinit; 1721043Sbill strncat(homedir, pwd->pw_dir, sizeof(homedir)-6); 1731043Sbill strncat(shell, pwd->pw_shell, sizeof(shell)-7); 1741043Sbill strncat(term, stypeof(ttyn), sizeof(term)-6); 1751043Sbill if ((namep = rindex(pwd->pw_shell, '/')) == NULL) 1761043Sbill namep = pwd->pw_shell; 1771043Sbill else 1781043Sbill namep++; 1791043Sbill strcat(minusnam, namep); 1801043Sbill alarm(0); 1811043Sbill umask(022); 1821043Sbill showmotd(); 1831043Sbill strcat(maildir, pwd->pw_name); 1841043Sbill if(access(maildir,4)==0) { 1851043Sbill struct stat statb; 1861043Sbill stat(maildir, &statb); 1871043Sbill if (statb.st_size) 1881043Sbill printf("You have mail.\n"); 1891043Sbill } 1901043Sbill signal(SIGQUIT, SIG_DFL); 1911043Sbill signal(SIGINT, SIG_DFL); 1921043Sbill execlp(pwd->pw_shell, minusnam, 0); 1931043Sbill printf("No shell\n"); 1941043Sbill exit(0); 1951043Sbill } 1961043Sbill 1971043Sbill int stopmotd; 1981043Sbill catch() 1991043Sbill { 2001043Sbill signal(SIGINT, SIG_IGN); 2011043Sbill stopmotd++; 2021043Sbill } 2031043Sbill 2041043Sbill showmotd() 2051043Sbill { 2061043Sbill FILE *mf; 2071043Sbill register c; 2081043Sbill 2091043Sbill signal(SIGINT, catch); 2101043Sbill if((mf = fopen("/etc/motd","r")) != NULL) { 2111043Sbill while((c = getc(mf)) != EOF && stopmotd == 0) 2121043Sbill putchar(c); 2131043Sbill fclose(mf); 2141043Sbill } 2151043Sbill signal(SIGINT, SIG_IGN); 2161043Sbill } 2171043Sbill 2181043Sbill #define UNKNOWN "su" 2191043Sbill 2201043Sbill char * 2211043Sbill stypeof(ttyid) 2221043Sbill char *ttyid; 2231043Sbill { 2241043Sbill static char typebuf[16]; 2251043Sbill char buf[50]; 2261043Sbill register FILE *f; 2271043Sbill register char *p, *t, *q; 2281043Sbill 2291043Sbill if (ttyid == NULL) 2301043Sbill return (UNKNOWN); 2311043Sbill f = fopen("/etc/ttytype", "r"); 2321043Sbill if (f == NULL) 2331043Sbill return (UNKNOWN); 2341043Sbill /* split off end of name */ 2351043Sbill for (p = q = ttyid; *p != 0; p++) 2361043Sbill if (*p == '/') 2371043Sbill q = p + 1; 2381043Sbill 2391043Sbill /* scan the file */ 2401043Sbill while (fgets(buf, sizeof buf, f) != NULL) 2411043Sbill { 2421043Sbill for (t=buf; *t!=' '; t++) 2431043Sbill ; 2441043Sbill *t++ = 0; 2451043Sbill for (p=t; *p>' '; p++) 2461043Sbill ; 2471043Sbill *p = 0; 2481043Sbill if (strcmp(q,t)==0) { 2491043Sbill strcpy(typebuf, buf); 2501043Sbill fclose(f); 2511043Sbill return (typebuf); 2521043Sbill } 2531043Sbill } 2541043Sbill fclose (f); 2551043Sbill return (UNKNOWN); 2561043Sbill } 257