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