1*1043Sbill static char *sccsid = "@(#)login.c 4.1 (Berkeley) 10/01/80"; 2*1043Sbill /* 3*1043Sbill * login [ name ] 4*1043Sbill */ 5*1043Sbill 6*1043Sbill #include <sys/types.h> 7*1043Sbill #include <sgtty.h> 8*1043Sbill #include <utmp.h> 9*1043Sbill #include <signal.h> 10*1043Sbill #include <pwd.h> 11*1043Sbill #include <stdio.h> 12*1043Sbill #include <sys/stat.h> 13*1043Sbill #include <lastlog.h> 14*1043Sbill #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 15*1043Sbill 16*1043Sbill #define NMAX sizeof(utmp.ut_name) 17*1043Sbill #define LMAX sizeof(utmp.ut_line) 18*1043Sbill 19*1043Sbill char user[20]; 20*1043Sbill char maildir[30] = "/usr/spool/mail/"; 21*1043Sbill char lastlog[] = "/usr/adm/lastlog"; 22*1043Sbill struct passwd nouser = {"", "nope"}; 23*1043Sbill struct sgttyb ttyb; 24*1043Sbill struct utmp utmp; 25*1043Sbill char minusnam[16] = "-"; 26*1043Sbill char homedir[64] = "HOME="; 27*1043Sbill char shell[64] = "SHELL="; 28*1043Sbill char term[64] = "TERM="; 29*1043Sbill char *envinit[] = {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", term, user,0}; 30*1043Sbill struct passwd *pwd; 31*1043Sbill 32*1043Sbill struct passwd *getpwnam(); 33*1043Sbill char *strcat(); 34*1043Sbill int setpwent(); 35*1043Sbill char *ttyname(); 36*1043Sbill char *crypt(); 37*1043Sbill char *getpass(); 38*1043Sbill char *rindex(); 39*1043Sbill char *stypeof(); 40*1043Sbill extern char **environ; 41*1043Sbill 42*1043Sbill main(argc, argv) 43*1043Sbill char **argv; 44*1043Sbill { 45*1043Sbill register char *namep; 46*1043Sbill int t, f, c; 47*1043Sbill char *ttyn; 48*1043Sbill int ldisc = 0; 49*1043Sbill 50*1043Sbill alarm(60); 51*1043Sbill signal(SIGQUIT, SIG_IGN); 52*1043Sbill signal(SIGINT, SIG_IGN); 53*1043Sbill nice(-100); 54*1043Sbill nice(20); 55*1043Sbill nice(0); 56*1043Sbill ioctl(0, TIOCLSET, 0); 57*1043Sbill ioctl(0, TIOCNXCL, 0); 58*1043Sbill gtty(0, &ttyb); 59*1043Sbill ttyb.sg_erase = '#'; 60*1043Sbill ttyb.sg_kill = '@'; 61*1043Sbill stty(0, &ttyb); 62*1043Sbill for (t=3; t<20; t++) 63*1043Sbill close(t); 64*1043Sbill ttyn = ttyname(0); 65*1043Sbill if (ttyn==0) 66*1043Sbill ttyn = "/dev/tty??"; 67*1043Sbill 68*1043Sbill loop: 69*1043Sbill ldisc = 0; 70*1043Sbill ioctl(0, TIOCSETD, &ldisc); 71*1043Sbill SCPYN(utmp.ut_name, ""); 72*1043Sbill if (argc>1) { 73*1043Sbill SCPYN(utmp.ut_name, argv[1]); 74*1043Sbill argc = 0; 75*1043Sbill } 76*1043Sbill while (utmp.ut_name[0] == '\0') { 77*1043Sbill namep = utmp.ut_name; 78*1043Sbill printf("login: "); 79*1043Sbill while ((c = getchar()) != '\n') { 80*1043Sbill if(c == ' ') 81*1043Sbill c = '_'; 82*1043Sbill if (c == EOF) 83*1043Sbill exit(0); 84*1043Sbill if (namep < utmp.ut_name+NMAX) 85*1043Sbill *namep++ = c; 86*1043Sbill } 87*1043Sbill } 88*1043Sbill setpwent(); 89*1043Sbill if ((pwd = getpwnam(utmp.ut_name)) == NULL) 90*1043Sbill pwd = &nouser; 91*1043Sbill endpwent(); 92*1043Sbill if (!strcmp(pwd->pw_shell, "/bin/csh")) { 93*1043Sbill ldisc = NTTYDISC; 94*1043Sbill ioctl(0, TIOCSETD, &ldisc); 95*1043Sbill } 96*1043Sbill if (*pwd->pw_passwd != '\0') { 97*1043Sbill nice(-4); 98*1043Sbill namep = crypt(getpass("Password:"),pwd->pw_passwd); 99*1043Sbill nice(4); 100*1043Sbill if (strcmp(namep, pwd->pw_passwd)) { 101*1043Sbill bad: 102*1043Sbill printf("Login incorrect\n"); 103*1043Sbill if (ttyn[LMAX] == 'd') { 104*1043Sbill FILE *console = fopen("/dev/console", "w"); 105*1043Sbill if (console != NULL) { 106*1043Sbill fprintf(console, "\r\nBADDIALUP %s %s\r\n", ttyn+5, utmp.ut_name); 107*1043Sbill fclose(console); 108*1043Sbill } 109*1043Sbill } 110*1043Sbill goto loop; 111*1043Sbill } 112*1043Sbill } 113*1043Sbill sprintf(user, "USER=%.*s", NMAX, pwd->pw_name); 114*1043Sbill if (pwd->pw_uid == 0 && ttyn[5] != 'c') 115*1043Sbill goto bad; 116*1043Sbill if (ttyn[LMAX] == 'd') { 117*1043Sbill FILE *console = fopen("/dev/console", "w"); 118*1043Sbill if (console != NULL) { 119*1043Sbill fprintf(console, "\r\nDIALUP %s %s\r\n", ttyn+5, pwd->pw_name); 120*1043Sbill fclose(console); 121*1043Sbill } 122*1043Sbill } 123*1043Sbill if((f = open(lastlog, 2)) >= 0) { 124*1043Sbill struct lastlog ll; 125*1043Sbill 126*1043Sbill lseek(f, pwd->pw_uid * sizeof (struct lastlog), 0); 127*1043Sbill if (read(f, (char *) &ll, sizeof ll) == sizeof ll && ll.ll_time != 0) { 128*1043Sbill register char *ep = (char *) ctime(&ll.ll_time); 129*1043Sbill printf("Last login: "); 130*1043Sbill ep[24 - 5] = 0; 131*1043Sbill printf("%s on %.*s\n", ep, LMAX, ll.ll_line); 132*1043Sbill } 133*1043Sbill lseek(f, pwd->pw_uid * sizeof (struct lastlog), 0); 134*1043Sbill time(&ll.ll_time); 135*1043Sbill strcpyn(ll.ll_line, ttyn+5, LMAX); 136*1043Sbill write(f, (char *) &ll, sizeof ll); 137*1043Sbill close(f); 138*1043Sbill } 139*1043Sbill if(chdir(pwd->pw_dir) < 0) { 140*1043Sbill printf("No directory\n"); 141*1043Sbill goto loop; 142*1043Sbill } 143*1043Sbill time(&utmp.ut_time); 144*1043Sbill t = ttyslot(); 145*1043Sbill if (t>0 && (f = open("/etc/utmp", 1)) >= 0) { 146*1043Sbill lseek(f, (long)(t*sizeof(utmp)), 0); 147*1043Sbill SCPYN(utmp.ut_line, rindex(ttyn, '/')+1); 148*1043Sbill write(f, (char *)&utmp, sizeof(utmp)); 149*1043Sbill close(f); 150*1043Sbill } 151*1043Sbill if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) { 152*1043Sbill lseek(f, 0L, 2); 153*1043Sbill write(f, (char *)&utmp, sizeof(utmp)); 154*1043Sbill close(f); 155*1043Sbill } 156*1043Sbill chown(ttyn, pwd->pw_uid, pwd->pw_gid); 157*1043Sbill setgid(pwd->pw_gid); 158*1043Sbill setuid(pwd->pw_uid); 159*1043Sbill if (*pwd->pw_shell == '\0') 160*1043Sbill pwd->pw_shell = "/bin/sh"; 161*1043Sbill environ = envinit; 162*1043Sbill strncat(homedir, pwd->pw_dir, sizeof(homedir)-6); 163*1043Sbill strncat(shell, pwd->pw_shell, sizeof(shell)-7); 164*1043Sbill strncat(term, stypeof(ttyn), sizeof(term)-6); 165*1043Sbill if ((namep = rindex(pwd->pw_shell, '/')) == NULL) 166*1043Sbill namep = pwd->pw_shell; 167*1043Sbill else 168*1043Sbill namep++; 169*1043Sbill strcat(minusnam, namep); 170*1043Sbill alarm(0); 171*1043Sbill umask(022); 172*1043Sbill showmotd(); 173*1043Sbill strcat(maildir, pwd->pw_name); 174*1043Sbill if(access(maildir,4)==0) { 175*1043Sbill struct stat statb; 176*1043Sbill stat(maildir, &statb); 177*1043Sbill if (statb.st_size) 178*1043Sbill printf("You have mail.\n"); 179*1043Sbill } 180*1043Sbill signal(SIGQUIT, SIG_DFL); 181*1043Sbill signal(SIGINT, SIG_DFL); 182*1043Sbill execlp(pwd->pw_shell, minusnam, 0); 183*1043Sbill printf("No shell\n"); 184*1043Sbill exit(0); 185*1043Sbill } 186*1043Sbill 187*1043Sbill int stopmotd; 188*1043Sbill catch() 189*1043Sbill { 190*1043Sbill signal(SIGINT, SIG_IGN); 191*1043Sbill stopmotd++; 192*1043Sbill } 193*1043Sbill 194*1043Sbill showmotd() 195*1043Sbill { 196*1043Sbill FILE *mf; 197*1043Sbill register c; 198*1043Sbill 199*1043Sbill signal(SIGINT, catch); 200*1043Sbill if((mf = fopen("/etc/motd","r")) != NULL) { 201*1043Sbill while((c = getc(mf)) != EOF && stopmotd == 0) 202*1043Sbill putchar(c); 203*1043Sbill fclose(mf); 204*1043Sbill } 205*1043Sbill signal(SIGINT, SIG_IGN); 206*1043Sbill } 207*1043Sbill 208*1043Sbill #define UNKNOWN "su" 209*1043Sbill 210*1043Sbill char * 211*1043Sbill stypeof(ttyid) 212*1043Sbill char *ttyid; 213*1043Sbill { 214*1043Sbill static char typebuf[16]; 215*1043Sbill char buf[50]; 216*1043Sbill register FILE *f; 217*1043Sbill register char *p, *t, *q; 218*1043Sbill 219*1043Sbill if (ttyid == NULL) 220*1043Sbill return (UNKNOWN); 221*1043Sbill f = fopen("/etc/ttytype", "r"); 222*1043Sbill if (f == NULL) 223*1043Sbill return (UNKNOWN); 224*1043Sbill /* split off end of name */ 225*1043Sbill for (p = q = ttyid; *p != 0; p++) 226*1043Sbill if (*p == '/') 227*1043Sbill q = p + 1; 228*1043Sbill 229*1043Sbill /* scan the file */ 230*1043Sbill while (fgets(buf, sizeof buf, f) != NULL) 231*1043Sbill { 232*1043Sbill for (t=buf; *t!=' '; t++) 233*1043Sbill ; 234*1043Sbill *t++ = 0; 235*1043Sbill for (p=t; *p>' '; p++) 236*1043Sbill ; 237*1043Sbill *p = 0; 238*1043Sbill if (strcmp(q,t)==0) { 239*1043Sbill strcpy(typebuf, buf); 240*1043Sbill fclose(f); 241*1043Sbill return (typebuf); 242*1043Sbill } 243*1043Sbill } 244*1043Sbill fclose (f); 245*1043Sbill return (UNKNOWN); 246*1043Sbill } 247