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