Commit | Line | Data |
---|---|---|
bcc34e0d BJ |
1 | # |
2 | /* | |
3 | * login [ name ] | |
4 | */ | |
5 | ||
6 | struct { | |
7 | char name[8]; | |
8 | char tty; | |
9 | char ifill; | |
10 | int time[2]; | |
11 | int uuid; | |
12 | } utmp, xtmp; | |
13 | ||
14 | struct { | |
15 | int speeds; | |
16 | char erase, kill; | |
17 | int tflags; | |
18 | } ttyb; | |
19 | ||
20 | struct { | |
21 | int junk[5]; | |
22 | int size; | |
23 | int more[12]; | |
24 | } statb; | |
25 | ||
26 | extern htmp; | |
27 | struct { | |
28 | int l_tty; | |
29 | int l_time[2]; | |
30 | } last; | |
31 | ||
32 | char mailfile[] "/usr/mail/xxxxxxxx"; | |
33 | char kickoff[] "/etc/kickoff"; | |
34 | char lastlog[] "/usr/adm/lastlog/XXXX"; | |
35 | ||
36 | char *ttyx; | |
37 | ||
38 | #define ECHO 010 | |
39 | ||
40 | main(argc, argv) | |
41 | char **argv; | |
42 | { | |
43 | char pbuf[128]; | |
44 | register char *namep, *np, *mp; | |
45 | int quiet; | |
46 | char pwbuf[9], *cp, *ll; | |
47 | int t, sflags, f, c, uid, gid, badname; | |
48 | ||
49 | alarm(300); /* 5 minutes to log in */ | |
50 | signal(3, 1); | |
51 | signal(2, 1); | |
52 | nice(-2); | |
53 | ttyx = "/dev/ttyx"; | |
54 | if ((utmp.tty=ttyn(0)) == 'x') { | |
55 | write(1, "Sorry.\n", 7); | |
56 | exit(); | |
57 | } | |
58 | ttyx[8] = utmp.tty; | |
59 | loop: | |
60 | badname = 0; | |
61 | namep = utmp.name; | |
62 | mp = &mailfile[10]; | |
63 | if (argc>1) { | |
64 | np = argv[1]; | |
65 | while (namep<utmp.name+8 && *np) { | |
66 | *mp++ = *np; | |
67 | *namep++ = *np++; | |
68 | } | |
69 | argc = 0; | |
70 | } else { | |
71 | write(1, "Name: ", 7); | |
72 | while ((c = getchar()) != '\n') { | |
73 | if (c <= 0) | |
74 | exit(); | |
75 | if (namep < utmp.name+8) { | |
76 | *mp++ = c; | |
77 | *namep++ = c; | |
78 | } | |
79 | } | |
80 | if(namep == utmp.name) | |
81 | goto loop; | |
82 | } | |
83 | while (namep < utmp.name+8) | |
84 | *namep++ = ' '; | |
85 | *mp = '\0'; | |
86 | if (getpwentry(utmp.name, pbuf, "/etc/passwdf")) { | |
87 | badname++; | |
88 | goto askpw; | |
89 | } | |
90 | mp = np = colon(pbuf); | |
91 | if (*np!=':') { | |
92 | askpw: | |
93 | gtty(0, &ttyb); | |
94 | sflags = ttyb.tflags; | |
95 | ttyb.tflags =& ~ ECHO; | |
96 | stty(0, &ttyb); | |
97 | write(1, "Password: ", 10); | |
98 | namep = pwbuf; | |
99 | while ((c=getchar()) != '\n') { | |
100 | if (c <= 0) | |
101 | exit(); | |
102 | if (namep<pwbuf+8) | |
103 | *namep++ = c; | |
104 | } | |
105 | *namep++ = '\0'; | |
106 | ttyb.tflags = sflags; | |
107 | stty(0, &ttyb); | |
108 | write(1, "\n", 1); | |
109 | namep = crypt(pwbuf); | |
110 | while (*namep++ == *np++); | |
111 | if (*--namep== '\0' && *--np ==':') | |
112 | goto good; | |
113 | namep = crypt(pwbuf); | |
114 | np = mp; | |
115 | while (*namep++ == *np++); | |
116 | if (*--namep!= '\0' || *--np !=':' || badname) | |
117 | goto bad; | |
118 | good: ; | |
119 | } | |
120 | if (getpwentry(utmp.name, pbuf, "/etc/passwd")) | |
121 | goto bad; | |
122 | np = colon(pbuf); | |
123 | np = colon(np); | |
124 | uid = 0; | |
125 | while (*np != ':') | |
126 | uid = uid*10 + *np++ - '0'; | |
127 | np++; | |
128 | ll = &lastlog[17]; | |
129 | gid = 0; | |
130 | while (*np != ':') { | |
131 | *ll++ = *np; | |
132 | gid = gid*10 + *np++ - '0'; | |
133 | } | |
134 | *ll = 0; | |
135 | np++; | |
136 | np = colon(np); | |
137 | namep = np; | |
138 | np = colon(np); | |
139 | time(utmp.time); | |
140 | utmp.uuid = (gid<<8)|uid; | |
141 | if ((f = open("/etc/utmp", 1)) >= 0) { | |
142 | t = utmp.tty; | |
143 | seek(f, (t&0177)*16, 0); | |
144 | write(f, &utmp, 16); | |
145 | close(f); | |
146 | } | |
147 | if ((f = open("/usr/adm/wtmp", 1)) >= 0) { | |
148 | seek(f, 0, 2); | |
149 | write(f, &utmp, 16); | |
150 | close(f); | |
151 | } | |
152 | f = gid<<8 | uid; | |
153 | if (f == 0) | |
154 | if (utmp.tty!='5' && utmp.tty!='8' && utmp.tty!='t') | |
155 | goto bad; | |
156 | if ((f=open(lastlog, 2)) < 0) { | |
157 | if ((f=creat(lastlog, 0600)) < 0) | |
158 | goto cont; | |
159 | close(f); | |
160 | if ((f=open(lastlog, 2)) < 0) | |
161 | goto cont; | |
162 | } | |
163 | seek(f, uid*6, 0); | |
164 | if (read(f, &last.l_tty, 6) == 6) { | |
165 | if (last.l_time[0]) { | |
166 | ll = ctime(last.l_time); | |
167 | c = ' '; | |
168 | if (last.l_tty < 033) { | |
169 | c = last.l_tty - 1 + 'a'; | |
170 | last.l_tty = '^'; | |
171 | } | |
172 | printf("Last login: %.16s on tty%c%c\n", ll, last.l_tty, c); | |
173 | } | |
174 | } | |
175 | seek(f, uid*6, 0); | |
176 | write(f, &utmp.tty, 6); | |
177 | close(f); | |
178 | cont: | |
179 | quiet = 0; | |
180 | if(utmp.name[0] >= 'A' && utmp.name[0] <= 'Z') | |
181 | quiet++; | |
182 | if(!quiet) | |
183 | if ((f = open("/etc/motd", 0)) >= 0) { | |
184 | while ((t=read(f, &xtmp, sizeof xtmp)) > 0) | |
185 | write(1, &xtmp, t); | |
186 | close(f); | |
187 | } | |
188 | if(!quiet) | |
189 | if(stat(mailfile, &statb) >= 0 && statb.size) | |
190 | write(1, "You have mail.\n", 15); | |
191 | chown(ttyx, gid<<8|uid); | |
192 | hsetuid(gid << 8 | uid); | |
193 | hsethome(namep); | |
194 | hsettype(typeof(utmp.tty)); | |
195 | hput(utmp.tty); | |
196 | setuid(gid<<8 | uid); | |
197 | f = 0; | |
198 | if (fork() == 0) { | |
199 | execl(kickoff, "kickoff", 0); | |
200 | exit(); | |
201 | } else { | |
202 | if (gid || uid) { | |
203 | wait(&f); | |
204 | if (f>>8 != 0) { | |
205 | printf("priority too low to log in\n"); | |
206 | exit(); | |
207 | } | |
208 | } | |
209 | } | |
210 | for (;;) { | |
211 | if (*namep == '\0') | |
212 | break; | |
213 | cp = namep++; | |
214 | for (; *namep != '/' && *namep != '\0'; namep++); | |
215 | if (*namep == '/') | |
216 | *namep++ = '\0'; | |
217 | if (chdir(cp)<0) { | |
218 | write(1, "No directory\n", 13); | |
219 | exit(); | |
220 | } | |
221 | alarm(0); | |
222 | if(!quiet) | |
223 | if ((f = open(".reminder", 0)) >= 0) { | |
224 | while ((t=read(f, &utmp, sizeof utmp)) > 0) | |
225 | write(1, &utmp, t); | |
226 | close(f); | |
227 | } | |
228 | } | |
229 | nice(0); | |
230 | if (*np == '\0') | |
231 | np = "/bin/sh"; | |
232 | if (stat(".start_up", &statb) >= 0 && statb.size) | |
233 | if (fork() == 0) { | |
234 | execl("/bin/sh", "-", ".start_up", 0); | |
235 | exit(); | |
236 | } else | |
237 | wait(&f); | |
238 | execl(np, "-", 0); | |
239 | write(1, "No shell.\n", 9); | |
240 | exit(); | |
241 | bad: | |
242 | write(1, "Login incorrect.\n", 17); | |
243 | goto loop; | |
244 | } | |
245 | ||
246 | getpwentry(name, buf, fname) | |
247 | char *name, *buf; | |
248 | { | |
249 | extern fin; | |
250 | int fi, r, c; | |
251 | register char *gnp, *rnp; | |
252 | ||
253 | fi = fin; | |
254 | r = 1; | |
255 | if((fin = open(fname, 0)) < 0) | |
256 | goto ret; | |
257 | loop: | |
258 | gnp = name; | |
259 | rnp = buf; | |
260 | while((c=getchar()) != '\n') { | |
261 | if(c <= 0) | |
262 | goto ret; | |
263 | *rnp++ = c; | |
264 | } | |
265 | *rnp++ = '\0'; | |
266 | rnp = buf; | |
267 | while (*gnp++ == *rnp++); | |
268 | if ((*--gnp!=' ' && gnp<name+8) || *--rnp!=':') | |
269 | goto loop; | |
270 | r = 0; | |
271 | ret: | |
272 | close(fin); | |
273 | fin = 0; | |
274 | (&fin)[1] = 0; | |
275 | (&fin)[2] = 0; | |
276 | return(r); | |
277 | } | |
278 | ||
279 | colon(p) | |
280 | char *p; | |
281 | { | |
282 | register char *rp; | |
283 | ||
284 | rp = p; | |
285 | while (*rp != ':') { | |
286 | if (*rp++ == '\0') { | |
287 | write(1, "Bad /etc/passwd\n", 16); | |
288 | exit(); | |
289 | } | |
290 | } | |
291 | *rp++ = '\0'; | |
292 | return(rp); | |
293 | } |