1: /* 2: * login [ name ] 3: */ 4: 5: #include <sys/types.h> 6: #include <sgtty.h> 7: #include <utmp.h> 8: #include <signal.h> 9: #include <pwd.h> 10: #include <stdio.h> 11: #include <sys/stat.h> 12: #define SCPYN(a, b) strncpy(a, b, sizeof(a)) 13: 14: char maildir[30] = "/usr/spool/mail/"; 15: struct passwd nouser = {"", "nope"}; 16: struct sgttyb ttyb; 17: struct utmp utmp; 18: char minusnam[16] = "-"; 19: char homedir[64] = "HOME="; 20: char *envinit[] = {homedir, "PATH=:/bin:/usr/bin", 0}; 21: struct passwd *pwd; 22: 23: struct passwd *getpwnam(); 24: char *strcat(); 25: int setpwent(); 26: char *ttyname(); 27: char *crypt(); 28: char *getpass(); 29: char *rindex(), *index(); 30: extern char **environ; 31: 32: main(argc, argv) 33: char **argv; 34: { 35: register char *namep; 36: int t, f, c; 37: char *ttyn; 38: 39: alarm(60); 40: signal(SIGQUIT, SIG_IGN); 41: signal(SIGINT, SIG_IGN); 42: nice(-100); 43: nice(20); 44: nice(0); 45: gtty(0, &ttyb); 46: ttyb.sg_erase = '#'; 47: ttyb.sg_kill = '@'; 48: stty(0, &ttyb); 49: for (t=3; t<20; t++) 50: close(t); 51: ttyn = ttyname(0); 52: if (ttyn==0) 53: ttyn = "/dev/tty??"; 54: 55: loop: 56: SCPYN(utmp.ut_name, ""); 57: if (argc>1) { 58: SCPYN(utmp.ut_name, argv[1]); 59: argc = 0; 60: } 61: while (utmp.ut_name[0] == '\0') { 62: namep = utmp.ut_name; 63: printf("login: "); 64: while ((c = getchar()) != '\n') { 65: if(c == ' ') 66: c = '_'; 67: if (c == EOF) 68: exit(0); 69: if (namep < utmp.ut_name+8) 70: *namep++ = c; 71: } 72: } 73: setpwent(); 74: if ((pwd = getpwnam(utmp.ut_name)) == NULL) 75: pwd = &nouser; 76: endpwent(); 77: if (*pwd->pw_passwd != '\0') { 78: namep = crypt(getpass("Password:"),pwd->pw_passwd); 79: if (strcmp(namep, pwd->pw_passwd)) { 80: printf("Login incorrect\n"); 81: goto loop; 82: } 83: } 84: if(chdir(pwd->pw_dir) < 0) { 85: printf("No directory\n"); 86: goto loop; 87: } 88: time(&utmp.ut_time); 89: t = ttyslot(); 90: if (t>0 && (f = open("/etc/utmp", 1)) >= 0) { 91: lseek(f, (long)(t*sizeof(utmp)), 0); 92: SCPYN(utmp.ut_line, index(ttyn+1, '/')+1); 93: write(f, (char *)&utmp, sizeof(utmp)); 94: close(f); 95: } 96: if (t>0 && (f = open("/usr/adm/wtmp", 1)) >= 0) { 97: lseek(f, 0L, 2); 98: write(f, (char *)&utmp, sizeof(utmp)); 99: close(f); 100: } 101: chown(ttyn, pwd->pw_uid, pwd->pw_gid); 102: setgid(pwd->pw_gid); 103: setuid(pwd->pw_uid); 104: if (*pwd->pw_shell == '\0') 105: pwd->pw_shell = "/bin/sh"; 106: environ = envinit; 107: strncat(homedir, pwd->pw_dir, sizeof(homedir)-6); 108: if ((namep = rindex(pwd->pw_shell, '/')) == NULL) 109: namep = pwd->pw_shell; 110: else 111: namep++; 112: strcat(minusnam, namep); 113: alarm(0); 114: umask(02); 115: showmotd(); 116: strcat(maildir, pwd->pw_name); 117: if(access(maildir,4)==0) { 118: struct stat statb; 119: stat(maildir, &statb); 120: if (statb.st_size) 121: printf("You have mail.\n"); 122: } 123: signal(SIGQUIT, SIG_DFL); 124: signal(SIGINT, SIG_DFL); 125: execlp(pwd->pw_shell, minusnam, 0); 126: printf("No shell\n"); 127: exit(0); 128: } 129: 130: int stopmotd; 131: catch() 132: { 133: signal(SIGINT, SIG_IGN); 134: stopmotd++; 135: } 136: 137: showmotd() 138: { 139: FILE *mf; 140: register c; 141: 142: signal(SIGINT, catch); 143: if((mf = fopen("/etc/motd","r")) != NULL) { 144: while((c = getc(mf)) != EOF && stopmotd == 0) 145: putchar(c); 146: fclose(mf); 147: } 148: signal(SIGINT, SIG_IGN); 149: }