1*1365Sbill static char *sccsid = "@(#)login.c 4.2 (Berkeley) 10/10/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 42*1365Sbill #define CTRL(c) ('c'&037) 43*1365Sbill #define CERASE '#' 44*1365Sbill #define CEOT CTRL(d) 45*1365Sbill #define CKILL '@' 46*1365Sbill #define CQUIT 034 /* FS, cntl shift L */ 47*1365Sbill #define CINTR 0177 /* DEL */ 48*1365Sbill #define CSTOP CTRL(s) 49*1365Sbill #define CSTART CTRL(q) 50*1365Sbill #define CBRK 0377 51*1365Sbill struct tchars tc = { 52*1365Sbill CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK 53*1365Sbill }; 54*1365Sbill struct ltchars ltc = { 55*1365Sbill CTRL(z), CTRL(y), CTRL(r), CTRL(o), CTRL(w), CTRL(v), CTRL(h), CTRL(u), 56*1365Sbill CTRL(c) 57*1365Sbill }; 58*1365Sbill 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); 73*1365Sbill ioctl(0, TIOCSETD, &ldisc); 741043Sbill ioctl(0, TIOCLSET, 0); 751043Sbill gtty(0, &ttyb); 761043Sbill ttyb.sg_erase = '#'; 771043Sbill ttyb.sg_kill = '@'; 781043Sbill stty(0, &ttyb); 79*1365Sbill ioctl(0, TIOCSETC, &tc); 80*1365Sbill 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: 881043Sbill SCPYN(utmp.ut_name, ""); 891043Sbill if (argc>1) { 901043Sbill SCPYN(utmp.ut_name, argv[1]); 911043Sbill argc = 0; 921043Sbill } 931043Sbill while (utmp.ut_name[0] == '\0') { 941043Sbill namep = utmp.ut_name; 951043Sbill printf("login: "); 961043Sbill while ((c = getchar()) != '\n') { 971043Sbill if(c == ' ') 981043Sbill c = '_'; 991043Sbill if (c == EOF) 1001043Sbill exit(0); 1011043Sbill if (namep < utmp.ut_name+NMAX) 1021043Sbill *namep++ = c; 1031043Sbill } 1041043Sbill } 1051043Sbill setpwent(); 1061043Sbill if ((pwd = getpwnam(utmp.ut_name)) == NULL) 1071043Sbill pwd = &nouser; 1081043Sbill endpwent(); 1091043Sbill if (*pwd->pw_passwd != '\0') { 1101043Sbill namep = crypt(getpass("Password:"),pwd->pw_passwd); 1111043Sbill if (strcmp(namep, pwd->pw_passwd)) { 1121043Sbill bad: 1131043Sbill printf("Login incorrect\n"); 1141043Sbill if (ttyn[LMAX] == 'd') { 1151043Sbill FILE *console = fopen("/dev/console", "w"); 1161043Sbill if (console != NULL) { 1171043Sbill fprintf(console, "\r\nBADDIALUP %s %s\r\n", ttyn+5, utmp.ut_name); 1181043Sbill fclose(console); 1191043Sbill } 1201043Sbill } 1211043Sbill goto loop; 1221043Sbill } 1231043Sbill } 1241043Sbill sprintf(user, "USER=%.*s", NMAX, pwd->pw_name); 1251043Sbill if (pwd->pw_uid == 0 && ttyn[5] != 'c') 1261043Sbill goto bad; 1271043Sbill if (ttyn[LMAX] == 'd') { 1281043Sbill FILE *console = fopen("/dev/console", "w"); 1291043Sbill if (console != NULL) { 1301043Sbill fprintf(console, "\r\nDIALUP %s %s\r\n", ttyn+5, pwd->pw_name); 1311043Sbill fclose(console); 1321043Sbill } 1331043Sbill } 1341043Sbill if((f = open(lastlog, 2)) >= 0) { 1351043Sbill struct lastlog ll; 1361043Sbill 1371043Sbill lseek(f, pwd->pw_uid * sizeof (struct lastlog), 0); 1381043Sbill if (read(f, (char *) &ll, sizeof ll) == sizeof ll && ll.ll_time != 0) { 1391043Sbill register char *ep = (char *) ctime(&ll.ll_time); 1401043Sbill printf("Last login: "); 1411043Sbill ep[24 - 5] = 0; 1421043Sbill printf("%s on %.*s\n", ep, LMAX, ll.ll_line); 1431043Sbill } 1441043Sbill lseek(f, pwd->pw_uid * sizeof (struct lastlog), 0); 1451043Sbill time(&ll.ll_time); 1461043Sbill strcpyn(ll.ll_line, ttyn+5, LMAX); 1471043Sbill write(f, (char *) &ll, sizeof ll); 1481043Sbill close(f); 1491043Sbill } 1501043Sbill if(chdir(pwd->pw_dir) < 0) { 1511043Sbill printf("No directory\n"); 1521043Sbill goto loop; 1531043Sbill } 1541043Sbill time(&utmp.ut_time); 1551043Sbill t = ttyslot(); 1561043Sbill if (t>0 && (f = open("/etc/utmp", 1)) >= 0) { 1571043Sbill lseek(f, (long)(t*sizeof(utmp)), 0); 1581043Sbill SCPYN(utmp.ut_line, rindex(ttyn, '/')+1); 1591043Sbill write(f, (char *)&utmp, sizeof(utmp)); 1601043Sbill close(f); 1611043Sbill } 1621043Sbill if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) { 1631043Sbill lseek(f, 0L, 2); 1641043Sbill write(f, (char *)&utmp, sizeof(utmp)); 1651043Sbill close(f); 1661043Sbill } 1671043Sbill chown(ttyn, pwd->pw_uid, pwd->pw_gid); 1681043Sbill setgid(pwd->pw_gid); 1691043Sbill setuid(pwd->pw_uid); 1701043Sbill if (*pwd->pw_shell == '\0') 1711043Sbill pwd->pw_shell = "/bin/sh"; 1721043Sbill environ = envinit; 1731043Sbill strncat(homedir, pwd->pw_dir, sizeof(homedir)-6); 1741043Sbill strncat(shell, pwd->pw_shell, sizeof(shell)-7); 1751043Sbill strncat(term, stypeof(ttyn), sizeof(term)-6); 1761043Sbill if ((namep = rindex(pwd->pw_shell, '/')) == NULL) 1771043Sbill namep = pwd->pw_shell; 1781043Sbill else 1791043Sbill namep++; 1801043Sbill strcat(minusnam, namep); 1811043Sbill alarm(0); 1821043Sbill umask(022); 1831043Sbill showmotd(); 1841043Sbill strcat(maildir, pwd->pw_name); 1851043Sbill if(access(maildir,4)==0) { 1861043Sbill struct stat statb; 1871043Sbill stat(maildir, &statb); 1881043Sbill if (statb.st_size) 1891043Sbill printf("You have mail.\n"); 1901043Sbill } 1911043Sbill signal(SIGQUIT, SIG_DFL); 1921043Sbill signal(SIGINT, SIG_DFL); 1931043Sbill execlp(pwd->pw_shell, minusnam, 0); 1941043Sbill printf("No shell\n"); 1951043Sbill exit(0); 1961043Sbill } 1971043Sbill 1981043Sbill int stopmotd; 1991043Sbill catch() 2001043Sbill { 2011043Sbill signal(SIGINT, SIG_IGN); 2021043Sbill stopmotd++; 2031043Sbill } 2041043Sbill 2051043Sbill showmotd() 2061043Sbill { 2071043Sbill FILE *mf; 2081043Sbill register c; 2091043Sbill 2101043Sbill signal(SIGINT, catch); 2111043Sbill if((mf = fopen("/etc/motd","r")) != NULL) { 2121043Sbill while((c = getc(mf)) != EOF && stopmotd == 0) 2131043Sbill putchar(c); 2141043Sbill fclose(mf); 2151043Sbill } 2161043Sbill signal(SIGINT, SIG_IGN); 2171043Sbill } 2181043Sbill 2191043Sbill #define UNKNOWN "su" 2201043Sbill 2211043Sbill char * 2221043Sbill stypeof(ttyid) 2231043Sbill char *ttyid; 2241043Sbill { 2251043Sbill static char typebuf[16]; 2261043Sbill char buf[50]; 2271043Sbill register FILE *f; 2281043Sbill register char *p, *t, *q; 2291043Sbill 2301043Sbill if (ttyid == NULL) 2311043Sbill return (UNKNOWN); 2321043Sbill f = fopen("/etc/ttytype", "r"); 2331043Sbill if (f == NULL) 2341043Sbill return (UNKNOWN); 2351043Sbill /* split off end of name */ 2361043Sbill for (p = q = ttyid; *p != 0; p++) 2371043Sbill if (*p == '/') 2381043Sbill q = p + 1; 2391043Sbill 2401043Sbill /* scan the file */ 2411043Sbill while (fgets(buf, sizeof buf, f) != NULL) 2421043Sbill { 2431043Sbill for (t=buf; *t!=' '; t++) 2441043Sbill ; 2451043Sbill *t++ = 0; 2461043Sbill for (p=t; *p>' '; p++) 2471043Sbill ; 2481043Sbill *p = 0; 2491043Sbill if (strcmp(q,t)==0) { 2501043Sbill strcpy(typebuf, buf); 2511043Sbill fclose(f); 2521043Sbill return (typebuf); 2531043Sbill } 2541043Sbill } 2551043Sbill fclose (f); 2561043Sbill return (UNKNOWN); 2571043Sbill } 258