Commit | Line | Data |
---|---|---|
bcf1365c | 1 | /* |
5dbe2745 | 2 | * Copyright (c) 1980,1987 Regents of the University of California. |
bcf1365c DF |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
7 | #ifndef lint | |
8 | char copyright[] = | |
9 | "@(#) Copyright (c) 1980 Regents of the University of California.\n\ | |
10 | All rights reserved.\n"; | |
11 | #endif not lint | |
12 | ||
22d4760e | 13 | #ifndef lint |
b6f7cade | 14 | static char sccsid[] = "@(#)login.c 5.20 (Berkeley) %G%"; |
bcf1365c | 15 | #endif not lint |
22d4760e | 16 | |
88a01c09 BJ |
17 | /* |
18 | * login [ name ] | |
5dbe2745 MK |
19 | * login -r hostname (for rlogind) |
20 | * login -h hostname (for telnetd, etc.) | |
21 | * login -f name (for pre-authenticated login: datakit, xterm, etc.) | |
88a01c09 BJ |
22 | */ |
23 | ||
7a625b73 | 24 | #include <sys/param.h> |
3b8dd95e SL |
25 | #include <sys/quota.h> |
26 | #include <sys/stat.h> | |
27 | #include <sys/time.h> | |
28 | #include <sys/resource.h> | |
9479aa87 | 29 | #include <sys/file.h> |
3b8dd95e | 30 | |
88a01c09 BJ |
31 | #include <sgtty.h> |
32 | #include <utmp.h> | |
33 | #include <signal.h> | |
34 | #include <pwd.h> | |
35 | #include <stdio.h> | |
88a01c09 | 36 | #include <lastlog.h> |
22d4760e | 37 | #include <errno.h> |
9479aa87 BJ |
38 | #include <ttyent.h> |
39 | #include <syslog.h> | |
c89291e2 KM |
40 | #include <grp.h> |
41 | ||
9382c11c MK |
42 | #define TTYGRPNAME "tty" /* name of group to own ttys */ |
43 | #define TTYGID(gid) tty_gid(gid) /* gid that owns all ttys */ | |
f570e1ff | 44 | |
9479aa87 | 45 | #define SCMPN(a, b) strncmp(a, b, sizeof(a)) |
f570e1ff | 46 | #define SCPYN(a, b) strncpy(a, b, sizeof(a)) |
88a01c09 | 47 | |
b4389814 | 48 | #define NMAX sizeof(utmp.ut_name) |
df9d9536 | 49 | #define HMAX sizeof(utmp.ut_host) |
88a01c09 | 50 | |
f570e1ff BJ |
51 | #define FALSE 0 |
52 | #define TRUE -1 | |
53 | ||
54 | char nolog[] = "/etc/nologin"; | |
55 | char qlog[] = ".hushlogin"; | |
88a01c09 BJ |
56 | char maildir[30] = "/usr/spool/mail/"; |
57 | char lastlog[] = "/usr/adm/lastlog"; | |
3479a16a | 58 | struct passwd nouser = {"", "nope", -1, -1, -1, "", "", "", "" }; |
88a01c09 BJ |
59 | struct sgttyb ttyb; |
60 | struct utmp utmp; | |
61 | char minusnam[16] = "-"; | |
3daca631 | 62 | char *envinit[1]; /* now set by setenv calls */ |
3b8dd95e SL |
63 | /* |
64 | * This bounds the time given to login. We initialize it here | |
65 | * so it can be patched on machines where it's too small. | |
66 | */ | |
a9b031fe | 67 | int timeout = 300; |
86eb6c9e | 68 | |
d3737d51 | 69 | char term[64]; |
88a01c09 | 70 | |
86eb6c9e | 71 | struct passwd *pwd; |
3daca631 | 72 | char *strcat(), *rindex(), *index(); |
3b8dd95e | 73 | int timedout(); |
88a01c09 BJ |
74 | char *ttyname(); |
75 | char *crypt(); | |
76 | char *getpass(); | |
88a01c09 | 77 | char *stypeof(); |
22d4760e | 78 | extern int errno; |
88a01c09 | 79 | |
714accc5 SL |
80 | struct tchars tc = { |
81 | CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK | |
82 | }; | |
83 | struct ltchars ltc = { | |
84 | CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT | |
841d84b0 BJ |
85 | }; |
86 | ||
d3737d51 SL |
87 | struct winsize win = { 0, 0, 0, 0 }; |
88 | ||
86eb6c9e | 89 | int rflag; |
95a2c263 | 90 | int usererr = -1; |
b4389814 | 91 | char rusername[NMAX+1], lusername[NMAX+1]; |
86eb6c9e | 92 | char rpassword[NMAX+1]; |
e5321f7b | 93 | char name[NMAX+1]; |
53b3a5b2 | 94 | char me[MAXHOSTNAMELEN]; |
b4389814 | 95 | char *rhost; |
86eb6c9e | 96 | |
88a01c09 | 97 | main(argc, argv) |
3b8dd95e | 98 | char *argv[]; |
88a01c09 | 99 | { |
3daca631 | 100 | extern char **environ; |
88a01c09 | 101 | register char *namep; |
5dbe2745 | 102 | int pflag = 0, hflag = 0, fflag = 0, t, f, c; |
3b8dd95e | 103 | int invalid, quietlog; |
f570e1ff | 104 | FILE *nlfd; |
9479aa87 | 105 | char *ttyn, *tty; |
d3737d51 | 106 | int ldisc = 0, zero = 0, i; |
53b3a5b2 | 107 | char *p, *domain, *index(); |
88a01c09 | 108 | |
3b8dd95e SL |
109 | signal(SIGALRM, timedout); |
110 | alarm(timeout); | |
88a01c09 BJ |
111 | signal(SIGQUIT, SIG_IGN); |
112 | signal(SIGINT, SIG_IGN); | |
3b8dd95e | 113 | setpriority(PRIO_PROCESS, 0, 0); |
22d4760e | 114 | quota(Q_SETUID, 0, 0, 0); |
3b8dd95e | 115 | /* |
d3737d51 | 116 | * -p is used by getty to tell login not to destroy the environment |
3b8dd95e | 117 | * -r is used by rlogind to cause the autologin protocol; |
5dbe2745 | 118 | * -f is used to skip a second login authentication |
3b8dd95e SL |
119 | * -h is used by other servers to pass the name of the |
120 | * remote host to login so that it may be placed in utmp and wtmp | |
121 | */ | |
53b3a5b2 MK |
122 | (void) gethostname(me, sizeof(me)); |
123 | domain = index(me, '.'); | |
95a2c263 | 124 | while (argc > 1) { |
3b8dd95e | 125 | if (strcmp(argv[1], "-r") == 0) { |
5dbe2745 MK |
126 | if (rflag || hflag || fflag) { |
127 | printf("Other options not allowed with -r\n"); | |
95a2c263 JB |
128 | exit(1); |
129 | } | |
b6f7cade KB |
130 | if (argv[2] == 0) |
131 | exit(1); | |
95a2c263 JB |
132 | rflag = 1; |
133 | usererr = doremotelogin(argv[2]); | |
53b3a5b2 MK |
134 | if ((p = index(argv[2], '.')) && strcmp(p, domain) == 0) |
135 | *p = 0; | |
3b8dd95e | 136 | SCPYN(utmp.ut_host, argv[2]); |
95a2c263 JB |
137 | argc -= 2; |
138 | argv += 2; | |
139 | continue; | |
b4389814 | 140 | } |
5dbe2745 MK |
141 | if (strcmp(argv[1], "-h") == 0) { |
142 | if (getuid() == 0) { | |
143 | if (rflag || hflag) { | |
144 | printf("Only one of -r and -h allowed\n"); | |
145 | exit(1); | |
146 | } | |
147 | hflag = 1; | |
148 | if ((p = index(argv[2], '.')) && | |
149 | strcmp(p, domain) == 0) | |
150 | *p = 0; | |
151 | SCPYN(utmp.ut_host, argv[2]); | |
152 | } | |
153 | argc -= 2; | |
154 | argv += 2; | |
155 | continue; | |
156 | } | |
157 | if (strcmp(argv[1], "-f") == 0 && argc > 2) { | |
158 | if (rflag) { | |
159 | printf("Only one of -r and -f allowed\n"); | |
95a2c263 JB |
160 | exit(1); |
161 | } | |
5dbe2745 MK |
162 | fflag = 1; |
163 | SCPYN(utmp.ut_name, argv[2]); | |
95a2c263 JB |
164 | argc -= 2; |
165 | argv += 2; | |
166 | continue; | |
b4389814 | 167 | } |
d3737d51 SL |
168 | if (strcmp(argv[1], "-p") == 0) { |
169 | argc--; | |
170 | argv++; | |
171 | pflag = 1; | |
95a2c263 | 172 | continue; |
d3737d51 | 173 | } |
95a2c263 | 174 | break; |
86eb6c9e | 175 | } |
714accc5 | 176 | ioctl(0, TIOCLSET, &zero); |
c95ed2b2 | 177 | ioctl(0, TIOCNXCL, 0); |
4f8d3876 BJ |
178 | ioctl(0, FIONBIO, &zero); |
179 | ioctl(0, FIOASYNC, &zero); | |
714accc5 | 180 | ioctl(0, TIOCGETP, &ttyb); |
3b8dd95e SL |
181 | /* |
182 | * If talking to an rlogin process, | |
183 | * propagate the terminal type and | |
184 | * baud rate across the network. | |
185 | */ | |
186 | if (rflag) | |
187 | doremoteterm(term, &ttyb); | |
568353d4 MK |
188 | ttyb.sg_erase = CERASE; |
189 | ttyb.sg_kill = CKILL; | |
714accc5 SL |
190 | ioctl(0, TIOCSLTC, <c); |
191 | ioctl(0, TIOCSETC, &tc); | |
192 | ioctl(0, TIOCSETP, &ttyb); | |
c32fb087 | 193 | for (t = getdtablesize(); t > 2; t--) |
88a01c09 BJ |
194 | close(t); |
195 | ttyn = ttyname(0); | |
6fc1474b | 196 | if (ttyn == (char *)0 || *ttyn == '\0') |
88a01c09 | 197 | ttyn = "/dev/tty??"; |
9479aa87 BJ |
198 | tty = rindex(ttyn, '/'); |
199 | if (tty == NULL) | |
200 | tty = ttyn; | |
201 | else | |
202 | tty++; | |
076ae92c | 203 | openlog("login", LOG_ODELAY, LOG_AUTH); |
9479aa87 | 204 | t = 0; |
96aec705 | 205 | invalid = FALSE; |
f570e1ff BJ |
206 | do { |
207 | ldisc = 0; | |
c95ed2b2 | 208 | ioctl(0, TIOCSETD, &ldisc); |
5dbe2745 MK |
209 | if (fflag == 0) |
210 | SCPYN(utmp.ut_name, ""); | |
3b8dd95e SL |
211 | /* |
212 | * Name specified, take it. | |
213 | */ | |
214 | if (argc > 1) { | |
f570e1ff BJ |
215 | SCPYN(utmp.ut_name, argv[1]); |
216 | argc = 0; | |
217 | } | |
3b8dd95e SL |
218 | /* |
219 | * If remote login take given name, | |
220 | * otherwise prompt user for something. | |
221 | */ | |
96aec705 | 222 | if (rflag && !invalid) |
3479a16a | 223 | SCPYN(utmp.ut_name, lusername); |
b6f7cade | 224 | else { |
3b8dd95e | 225 | getloginname(&utmp); |
b6f7cade KB |
226 | if (utmp.ut_name[0] == '-') { |
227 | puts("login names may not start with '-'."); | |
228 | invalid = TRUE; | |
229 | continue; | |
230 | } | |
231 | } | |
96aec705 | 232 | invalid = FALSE; |
f570e1ff BJ |
233 | if (!strcmp(pwd->pw_shell, "/bin/csh")) { |
234 | ldisc = NTTYDISC; | |
235 | ioctl(0, TIOCSETD, &ldisc); | |
236 | } | |
5dbe2745 MK |
237 | if (fflag) { |
238 | int uid = getuid(); | |
239 | ||
240 | if (uid != 0 && uid != pwd->pw_uid) | |
241 | fflag = 0; | |
242 | /* | |
243 | * Disallow automatic login for root. | |
244 | */ | |
245 | if (pwd->pw_uid == 0) | |
246 | fflag = 0; | |
247 | } | |
3b8dd95e SL |
248 | /* |
249 | * If no remote login authentication and | |
250 | * a password exists for this user, prompt | |
251 | * for one and verify it. | |
252 | */ | |
5dbe2745 | 253 | if (usererr == -1 && fflag == 0 && *pwd->pw_passwd != '\0') { |
3b8dd95e SL |
254 | char *pp; |
255 | ||
256 | setpriority(PRIO_PROCESS, 0, -4); | |
257 | pp = getpass("Password:"); | |
258 | namep = crypt(pp, pwd->pw_passwd); | |
259 | setpriority(PRIO_PROCESS, 0, 0); | |
260 | if (strcmp(namep, pwd->pw_passwd)) | |
261 | invalid = TRUE; | |
f570e1ff | 262 | } |
3b8dd95e SL |
263 | /* |
264 | * If user not super-user, check for logins disabled. | |
265 | */ | |
f570e1ff | 266 | if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) { |
f570e1ff BJ |
267 | while ((c = getc(nlfd)) != EOF) |
268 | putchar(c); | |
269 | fflush(stdout); | |
270 | sleep(5); | |
271 | exit(0); | |
272 | } | |
3b8dd95e SL |
273 | /* |
274 | * If valid so far and root is logging in, | |
275 | * see if root logins on this terminal are permitted. | |
276 | */ | |
9479aa87 | 277 | if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) { |
df9d9536 KM |
278 | if (utmp.ut_host[0]) |
279 | syslog(LOG_CRIT, | |
280 | "ROOT LOGIN REFUSED ON %s FROM %.*s", | |
281 | tty, HMAX, utmp.ut_host); | |
282 | else | |
283 | syslog(LOG_CRIT, | |
284 | "ROOT LOGIN REFUSED ON %s", tty); | |
f570e1ff BJ |
285 | invalid = TRUE; |
286 | } | |
287 | if (invalid) { | |
88a01c09 | 288 | printf("Login incorrect\n"); |
9479aa87 | 289 | if (++t >= 5) { |
df9d9536 | 290 | if (utmp.ut_host[0]) |
5dbe2745 MK |
291 | syslog(LOG_ERR, |
292 | "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s", | |
df9d9536 KM |
293 | tty, HMAX, utmp.ut_host, |
294 | NMAX, utmp.ut_name); | |
295 | else | |
5dbe2745 MK |
296 | syslog(LOG_ERR, |
297 | "REPEATED LOGIN FAILURES ON %s, %.*s", | |
df9d9536 | 298 | tty, NMAX, utmp.ut_name); |
9479aa87 | 299 | ioctl(0, TIOCHPCL, (struct sgttyb *) 0); |
d3737d51 | 300 | close(0), close(1), close(2); |
9479aa87 BJ |
301 | sleep(10); |
302 | exit(1); | |
303 | } | |
88a01c09 | 304 | } |
f570e1ff BJ |
305 | if (*pwd->pw_shell == '\0') |
306 | pwd->pw_shell = "/bin/sh"; | |
f570e1ff BJ |
307 | if (chdir(pwd->pw_dir) < 0 && !invalid ) { |
308 | if (chdir("/") < 0) { | |
309 | printf("No directory!\n"); | |
310 | invalid = TRUE; | |
311 | } else { | |
3b8dd95e SL |
312 | printf("No directory! %s\n", |
313 | "Logging in with home=/"); | |
f570e1ff BJ |
314 | pwd->pw_dir = "/"; |
315 | } | |
88a01c09 | 316 | } |
3b8dd95e SL |
317 | /* |
318 | * Remote login invalid must have been because | |
319 | * of a restriction of some sort, no extra chances. | |
320 | */ | |
95a2c263 | 321 | if (!usererr && invalid) |
86eb6c9e | 322 | exit(1); |
f570e1ff | 323 | } while (invalid); |
3b8dd95e SL |
324 | /* committed to login turn off timeout */ |
325 | alarm(0); | |
88a01c09 | 326 | |
790c9c8b | 327 | if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) { |
22d4760e SL |
328 | if (errno == EUSERS) |
329 | printf("%s.\n%s.\n", | |
330 | "Too many users logged on already", | |
331 | "Try again later"); | |
332 | else if (errno == EPROCLIM) | |
333 | printf("You have too many processes running.\n"); | |
334 | else | |
6821e9c5 | 335 | perror("quota (Q_SETUID)"); |
22d4760e SL |
336 | sleep(5); |
337 | exit(0); | |
338 | } | |
88a01c09 BJ |
339 | time(&utmp.ut_time); |
340 | t = ttyslot(); | |
9479aa87 | 341 | if (t > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) { |
88a01c09 | 342 | lseek(f, (long)(t*sizeof(utmp)), 0); |
9479aa87 | 343 | SCPYN(utmp.ut_line, tty); |
88a01c09 BJ |
344 | write(f, (char *)&utmp, sizeof(utmp)); |
345 | close(f); | |
346 | } | |
9479aa87 | 347 | if ((f = open("/usr/adm/wtmp", O_WRONLY|O_APPEND)) >= 0) { |
88a01c09 BJ |
348 | write(f, (char *)&utmp, sizeof(utmp)); |
349 | close(f); | |
350 | } | |
9479aa87 BJ |
351 | quietlog = access(qlog, F_OK) == 0; |
352 | if ((f = open(lastlog, O_RDWR)) >= 0) { | |
f570e1ff BJ |
353 | struct lastlog ll; |
354 | ||
355 | lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); | |
356 | if (read(f, (char *) &ll, sizeof ll) == sizeof ll && | |
3b8dd95e SL |
357 | ll.ll_time != 0 && !quietlog) { |
358 | printf("Last login: %.*s ", | |
359 | 24-5, (char *)ctime(&ll.ll_time)); | |
360 | if (*ll.ll_host != '\0') | |
361 | printf("from %.*s\n", | |
362 | sizeof (ll.ll_host), ll.ll_host); | |
363 | else | |
364 | printf("on %.*s\n", | |
365 | sizeof (ll.ll_line), ll.ll_line); | |
f570e1ff BJ |
366 | } |
367 | lseek(f, (long)pwd->pw_uid * sizeof (struct lastlog), 0); | |
368 | time(&ll.ll_time); | |
9479aa87 | 369 | SCPYN(ll.ll_line, tty); |
3b8dd95e | 370 | SCPYN(ll.ll_host, utmp.ut_host); |
f570e1ff BJ |
371 | write(f, (char *) &ll, sizeof ll); |
372 | close(f); | |
373 | } | |
9382c11c | 374 | chown(ttyn, pwd->pw_uid, TTYGID(pwd->pw_gid)); |
c32fb087 | 375 | if (!hflag && !rflag) /* XXX */ |
d3737d51 | 376 | ioctl(0, TIOCSWINSZ, &win); |
c89291e2 | 377 | chmod(ttyn, 0620); |
88a01c09 | 378 | setgid(pwd->pw_gid); |
e5321f7b KM |
379 | strncpy(name, utmp.ut_name, NMAX); |
380 | name[NMAX] = '\0'; | |
b1198826 | 381 | initgroups(name, pwd->pw_gid); |
22d4760e | 382 | quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0); |
88a01c09 | 383 | setuid(pwd->pw_uid); |
3daca631 | 384 | |
d3737d51 SL |
385 | /* destroy environment unless user has asked to preserve it */ |
386 | if (!pflag) | |
387 | environ = envinit; | |
3daca631 KB |
388 | setenv("HOME", pwd->pw_dir, 1); |
389 | setenv("SHELL", pwd->pw_shell, 1); | |
d3737d51 SL |
390 | if (term[0] == '\0') |
391 | strncpy(term, stypeof(tty), sizeof(term)); | |
3daca631 KB |
392 | setenv("TERM", term, 0); |
393 | setenv("USER", pwd->pw_name, 1); | |
394 | setenv("PATH", ":/usr/ucb:/bin:/usr/bin", 0); | |
d3737d51 | 395 | |
88a01c09 BJ |
396 | if ((namep = rindex(pwd->pw_shell, '/')) == NULL) |
397 | namep = pwd->pw_shell; | |
398 | else | |
399 | namep++; | |
400 | strcat(minusnam, namep); | |
9479aa87 | 401 | if (tty[sizeof("tty")-1] == 'd') |
d3737d51 SL |
402 | syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name); |
403 | if (pwd->pw_uid == 0) | |
df9d9536 KM |
404 | if (utmp.ut_host[0]) |
405 | syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s", | |
406 | tty, HMAX, utmp.ut_host); | |
407 | else | |
408 | syslog(LOG_NOTICE, "ROOT LOGIN %s", tty); | |
4f8d3876 | 409 | if (!quietlog) { |
6821e9c5 | 410 | struct stat st; |
d3737d51 | 411 | |
f570e1ff BJ |
412 | showmotd(); |
413 | strcat(maildir, pwd->pw_name); | |
6821e9c5 S |
414 | if (stat(maildir, &st) == 0 && st.st_size != 0) |
415 | printf("You have %smail.\n", | |
d3737d51 | 416 | (st.st_mtime > st.st_atime) ? "new " : ""); |
f570e1ff | 417 | } |
3b8dd95e | 418 | signal(SIGALRM, SIG_DFL); |
88a01c09 BJ |
419 | signal(SIGQUIT, SIG_DFL); |
420 | signal(SIGINT, SIG_DFL); | |
5f87416f | 421 | signal(SIGTSTP, SIG_IGN); |
88a01c09 | 422 | execlp(pwd->pw_shell, minusnam, 0); |
f570e1ff | 423 | perror(pwd->pw_shell); |
88a01c09 BJ |
424 | printf("No shell\n"); |
425 | exit(0); | |
426 | } | |
427 | ||
3b8dd95e SL |
428 | getloginname(up) |
429 | register struct utmp *up; | |
430 | { | |
431 | register char *namep; | |
5a786176 | 432 | char c; |
3b8dd95e | 433 | |
3b8dd95e | 434 | while (up->ut_name[0] == '\0') { |
d910ab7f | 435 | namep = up->ut_name; |
5a786176 | 436 | printf("login: "); |
3b8dd95e SL |
437 | while ((c = getchar()) != '\n') { |
438 | if (c == ' ') | |
439 | c = '_'; | |
440 | if (c == EOF) | |
441 | exit(0); | |
442 | if (namep < up->ut_name+NMAX) | |
443 | *namep++ = c; | |
444 | } | |
445 | } | |
d910ab7f EW |
446 | strncpy(lusername, up->ut_name, NMAX); |
447 | lusername[NMAX] = 0; | |
d910ab7f | 448 | if ((pwd = getpwnam(lusername)) == NULL) |
3b8dd95e | 449 | pwd = &nouser; |
3b8dd95e SL |
450 | } |
451 | ||
452 | timedout() | |
453 | { | |
454 | ||
455 | printf("Login timed out after %d seconds\n", timeout); | |
456 | exit(0); | |
457 | } | |
458 | ||
88a01c09 BJ |
459 | int stopmotd; |
460 | catch() | |
461 | { | |
1886582e | 462 | |
88a01c09 BJ |
463 | signal(SIGINT, SIG_IGN); |
464 | stopmotd++; | |
465 | } | |
466 | ||
f570e1ff | 467 | rootterm(tty) |
1886582e | 468 | char *tty; |
f570e1ff | 469 | { |
9479aa87 BJ |
470 | register struct ttyent *t; |
471 | ||
472 | if ((t = getttynam(tty)) != NULL) { | |
473 | if (t->ty_status & TTY_SECURE) | |
474 | return (1); | |
f570e1ff | 475 | } |
9479aa87 | 476 | return (0); |
f570e1ff BJ |
477 | } |
478 | ||
88a01c09 BJ |
479 | showmotd() |
480 | { | |
481 | FILE *mf; | |
482 | register c; | |
483 | ||
484 | signal(SIGINT, catch); | |
9479aa87 | 485 | if ((mf = fopen("/etc/motd", "r")) != NULL) { |
f570e1ff | 486 | while ((c = getc(mf)) != EOF && stopmotd == 0) |
88a01c09 BJ |
487 | putchar(c); |
488 | fclose(mf); | |
489 | } | |
490 | signal(SIGINT, SIG_IGN); | |
491 | } | |
492 | ||
f570e1ff | 493 | #undef UNKNOWN |
88a01c09 BJ |
494 | #define UNKNOWN "su" |
495 | ||
496 | char * | |
497 | stypeof(ttyid) | |
3b8dd95e | 498 | char *ttyid; |
88a01c09 | 499 | { |
9479aa87 | 500 | register struct ttyent *t; |
88a01c09 | 501 | |
9479aa87 | 502 | if (ttyid == NULL || (t = getttynam(ttyid)) == NULL) |
88a01c09 | 503 | return (UNKNOWN); |
9479aa87 | 504 | return (t->ty_type); |
88a01c09 | 505 | } |
86eb6c9e | 506 | |
3b8dd95e SL |
507 | doremotelogin(host) |
508 | char *host; | |
509 | { | |
3b8dd95e SL |
510 | getstr(rusername, sizeof (rusername), "remuser"); |
511 | getstr(lusername, sizeof (lusername), "locuser"); | |
d3737d51 | 512 | getstr(term, sizeof(term), "Terminal type"); |
4cf9fc9e SL |
513 | if (getuid()) { |
514 | pwd = &nouser; | |
95a2c263 | 515 | return(-1); |
4cf9fc9e | 516 | } |
3b8dd95e | 517 | pwd = getpwnam(lusername); |
4cf9fc9e SL |
518 | if (pwd == NULL) { |
519 | pwd = &nouser; | |
95a2c263 | 520 | return(-1); |
3b8dd95e | 521 | } |
95a2c263 | 522 | return(ruserok(host, (pwd->pw_uid == 0), rusername, lusername)); |
3b8dd95e SL |
523 | } |
524 | ||
86eb6c9e BJ |
525 | getstr(buf, cnt, err) |
526 | char *buf; | |
527 | int cnt; | |
528 | char *err; | |
529 | { | |
530 | char c; | |
531 | ||
532 | do { | |
533 | if (read(0, &c, 1) != 1) | |
534 | exit(1); | |
535 | if (--cnt < 0) { | |
536 | printf("%s too long\r\n", err); | |
537 | exit(1); | |
538 | } | |
539 | *buf++ = c; | |
540 | } while (c != 0); | |
541 | } | |
4f8d3876 | 542 | |
3b8dd95e SL |
543 | char *speeds[] = |
544 | { "0", "50", "75", "110", "134", "150", "200", "300", | |
545 | "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" }; | |
546 | #define NSPEEDS (sizeof (speeds) / sizeof (speeds[0])) | |
547 | ||
548 | doremoteterm(term, tp) | |
549 | char *term; | |
550 | struct sgttyb *tp; | |
551 | { | |
d3737d51 SL |
552 | register char *cp = index(term, '/'), **cpp; |
553 | char *speed; | |
3b8dd95e SL |
554 | |
555 | if (cp) { | |
d3737d51 SL |
556 | *cp++ = '\0'; |
557 | speed = cp; | |
558 | cp = index(speed, '/'); | |
559 | if (cp) | |
560 | *cp++ = '\0'; | |
561 | for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++) | |
562 | if (strcmp(*cpp, speed) == 0) { | |
563 | tp->sg_ispeed = tp->sg_ospeed = cpp-speeds; | |
3b8dd95e SL |
564 | break; |
565 | } | |
566 | } | |
567 | tp->sg_flags = ECHO|CRMOD|ANYP|XTABS; | |
568 | } | |
d3737d51 | 569 | |
9382c11c | 570 | tty_gid(default_gid) |
5576108a | 571 | int default_gid; |
c89291e2 KM |
572 | { |
573 | struct group *getgrnam(), *gr; | |
5576108a | 574 | int gid = default_gid; |
c89291e2 | 575 | |
9382c11c | 576 | gr = getgrnam(TTYGRPNAME); |
c89291e2 KM |
577 | if (gr != (struct group *) 0) |
578 | gid = gr->gr_gid; | |
579 | ||
580 | endgrent(); | |
581 | ||
5576108a | 582 | return (gid); |
c89291e2 | 583 | } |