login.c revision 1.1 1 1.1 cgd /*-
2 1.1 cgd * Copyright (c) 1980, 1987, 1988, 1991 The Regents of the University
3 1.1 cgd * of California. All rights reserved.
4 1.1 cgd *
5 1.1 cgd * Redistribution and use in source and binary forms, with or without
6 1.1 cgd * modification, are permitted provided that the following conditions
7 1.1 cgd * are met:
8 1.1 cgd * 1. Redistributions of source code must retain the above copyright
9 1.1 cgd * notice, this list of conditions and the following disclaimer.
10 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
11 1.1 cgd * notice, this list of conditions and the following disclaimer in the
12 1.1 cgd * documentation and/or other materials provided with the distribution.
13 1.1 cgd * 3. All advertising materials mentioning features or use of this software
14 1.1 cgd * must display the following acknowledgement:
15 1.1 cgd * This product includes software developed by the University of
16 1.1 cgd * California, Berkeley and its contributors.
17 1.1 cgd * 4. Neither the name of the University nor the names of its contributors
18 1.1 cgd * may be used to endorse or promote products derived from this software
19 1.1 cgd * without specific prior written permission.
20 1.1 cgd *
21 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.1 cgd * SUCH DAMAGE.
32 1.1 cgd */
33 1.1 cgd
34 1.1 cgd #ifndef lint
35 1.1 cgd char copyright[] =
36 1.1 cgd "@(#) Copyright (c) 1980, 1987, 1988, 1991 The Regents of the University of California.\n\
37 1.1 cgd All rights reserved.\n";
38 1.1 cgd #endif /* not lint */
39 1.1 cgd
40 1.1 cgd #ifndef lint
41 1.1 cgd static char sccsid[] = "@(#)login.c 5.73 (Berkeley) 6/29/91";
42 1.1 cgd #endif /* not lint */
43 1.1 cgd
44 1.1 cgd /*
45 1.1 cgd * login [ name ]
46 1.1 cgd * login -h hostname (for telnetd, etc.)
47 1.1 cgd * login -f name (for pre-authenticated login: datakit, xterm, etc.)
48 1.1 cgd */
49 1.1 cgd
50 1.1 cgd #include <sys/param.h>
51 1.1 cgd #include <sys/stat.h>
52 1.1 cgd #include <sys/time.h>
53 1.1 cgd #include <sys/resource.h>
54 1.1 cgd #include <sys/file.h>
55 1.1 cgd
56 1.1 cgd #include <utmp.h>
57 1.1 cgd #include <signal.h>
58 1.1 cgd #include <errno.h>
59 1.1 cgd #include <ttyent.h>
60 1.1 cgd #include <syslog.h>
61 1.1 cgd #include <grp.h>
62 1.1 cgd #include <pwd.h>
63 1.1 cgd #include <setjmp.h>
64 1.1 cgd #include <stdio.h>
65 1.1 cgd #include <string.h>
66 1.1 cgd #include <tzfile.h>
67 1.1 cgd #include "pathnames.h"
68 1.1 cgd
69 1.1 cgd #define TTYGRPNAME "tty" /* name of group to own ttys */
70 1.1 cgd
71 1.1 cgd /*
72 1.1 cgd * This bounds the time given to login. Not a define so it can
73 1.1 cgd * be patched on machines where it's too small.
74 1.1 cgd */
75 1.1 cgd int timeout = 300;
76 1.1 cgd int rootlogin;
77 1.1 cgd #ifdef KERBEROS
78 1.1 cgd int notickets = 1;
79 1.1 cgd char *instance;
80 1.1 cgd char *krbtkfile_env;
81 1.1 cgd int authok;
82 1.1 cgd #endif
83 1.1 cgd
84 1.1 cgd struct passwd *pwd;
85 1.1 cgd int failures;
86 1.1 cgd char term[64], *envinit[1], *hostname, *username, *tty;
87 1.1 cgd
88 1.1 cgd main(argc, argv)
89 1.1 cgd int argc;
90 1.1 cgd char **argv;
91 1.1 cgd {
92 1.1 cgd extern int optind;
93 1.1 cgd extern char *optarg, **environ;
94 1.1 cgd struct timeval tp;
95 1.1 cgd struct group *gr;
96 1.1 cgd register int ch;
97 1.1 cgd register char *p;
98 1.1 cgd int ask, fflag, hflag, pflag, cnt, uid;
99 1.1 cgd int quietlog, rval;
100 1.1 cgd char *domain, *salt, *ttyn;
101 1.1 cgd char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
102 1.1 cgd char localhost[MAXHOSTNAMELEN];
103 1.1 cgd char *ctime(), *ttyname(), *stypeof(), *crypt(), *getpass();
104 1.1 cgd time_t time();
105 1.1 cgd off_t lseek();
106 1.1 cgd void timedout();
107 1.1 cgd
108 1.1 cgd (void)signal(SIGALRM, timedout);
109 1.1 cgd (void)alarm((u_int)timeout);
110 1.1 cgd (void)signal(SIGQUIT, SIG_IGN);
111 1.1 cgd (void)signal(SIGINT, SIG_IGN);
112 1.1 cgd (void)setpriority(PRIO_PROCESS, 0, 0);
113 1.1 cgd
114 1.1 cgd openlog("login", LOG_ODELAY, LOG_AUTH);
115 1.1 cgd
116 1.1 cgd /*
117 1.1 cgd * -p is used by getty to tell login not to destroy the environment
118 1.1 cgd * -f is used to skip a second login authentication
119 1.1 cgd * -h is used by other servers to pass the name of the remote
120 1.1 cgd * host to login so that it may be placed in utmp and wtmp
121 1.1 cgd */
122 1.1 cgd domain = NULL;
123 1.1 cgd if (gethostname(localhost, sizeof(localhost)) < 0)
124 1.1 cgd syslog(LOG_ERR, "couldn't get local hostname: %m");
125 1.1 cgd else
126 1.1 cgd domain = index(localhost, '.');
127 1.1 cgd
128 1.1 cgd fflag = hflag = pflag = 0;
129 1.1 cgd uid = getuid();
130 1.1 cgd while ((ch = getopt(argc, argv, "fh:p")) != EOF)
131 1.1 cgd switch (ch) {
132 1.1 cgd case 'f':
133 1.1 cgd fflag = 1;
134 1.1 cgd break;
135 1.1 cgd case 'h':
136 1.1 cgd if (uid) {
137 1.1 cgd (void)fprintf(stderr,
138 1.1 cgd "login: -h option: %s\n", strerror(EPERM));
139 1.1 cgd exit(1);
140 1.1 cgd }
141 1.1 cgd hflag = 1;
142 1.1 cgd if (domain && (p = index(optarg, '.')) &&
143 1.1 cgd strcasecmp(p, domain) == 0)
144 1.1 cgd *p = 0;
145 1.1 cgd hostname = optarg;
146 1.1 cgd break;
147 1.1 cgd case 'p':
148 1.1 cgd pflag = 1;
149 1.1 cgd break;
150 1.1 cgd case '?':
151 1.1 cgd default:
152 1.1 cgd if (!uid)
153 1.1 cgd syslog(LOG_ERR, "invalid flag %c", ch);
154 1.1 cgd (void)fprintf(stderr,
155 1.1 cgd "usage: login [-fp] [-h hostname] [username]\n");
156 1.1 cgd exit(1);
157 1.1 cgd }
158 1.1 cgd argc -= optind;
159 1.1 cgd argv += optind;
160 1.1 cgd if (*argv) {
161 1.1 cgd username = *argv;
162 1.1 cgd ask = 0;
163 1.1 cgd } else
164 1.1 cgd ask = 1;
165 1.1 cgd
166 1.1 cgd for (cnt = getdtablesize(); cnt > 2; cnt--)
167 1.1 cgd close(cnt);
168 1.1 cgd
169 1.1 cgd ttyn = ttyname(0);
170 1.1 cgd if (ttyn == NULL || *ttyn == '\0') {
171 1.1 cgd (void)sprintf(tname, "%s??", _PATH_TTY);
172 1.1 cgd ttyn = tname;
173 1.1 cgd }
174 1.1 cgd if (tty = rindex(ttyn, '/'))
175 1.1 cgd ++tty;
176 1.1 cgd else
177 1.1 cgd tty = ttyn;
178 1.1 cgd
179 1.1 cgd for (cnt = 0;; ask = 1) {
180 1.1 cgd if (ask) {
181 1.1 cgd fflag = 0;
182 1.1 cgd getloginname();
183 1.1 cgd }
184 1.1 cgd #ifdef KERBEROS
185 1.1 cgd if ((instance = index(username, '.')) != NULL) {
186 1.1 cgd if (strncmp(instance, ".root", 5) == 0)
187 1.1 cgd rootlogin++;
188 1.1 cgd *instance++ = '\0';
189 1.1 cgd } else {
190 1.1 cgd rootlogin = 0;
191 1.1 cgd instance = "";
192 1.1 cgd }
193 1.1 cgd #else
194 1.1 cgd rootlogin = 0;
195 1.1 cgd #endif
196 1.1 cgd if (strlen(username) > UT_NAMESIZE)
197 1.1 cgd username[UT_NAMESIZE] = '\0';
198 1.1 cgd
199 1.1 cgd /*
200 1.1 cgd * Note if trying multiple user names; log failures for
201 1.1 cgd * previous user name, but don't bother logging one failure
202 1.1 cgd * for nonexistent name (mistyped username).
203 1.1 cgd */
204 1.1 cgd if (failures && strcmp(tbuf, username)) {
205 1.1 cgd if (failures > (pwd ? 0 : 1))
206 1.1 cgd badlogin(tbuf);
207 1.1 cgd failures = 0;
208 1.1 cgd }
209 1.1 cgd (void)strcpy(tbuf, username);
210 1.1 cgd
211 1.1 cgd if (pwd = getpwnam(username))
212 1.1 cgd salt = pwd->pw_passwd;
213 1.1 cgd else
214 1.1 cgd salt = "xx";
215 1.1 cgd
216 1.1 cgd /*
217 1.1 cgd * if we have a valid account name, and it doesn't have a
218 1.1 cgd * password, or the -f option was specified and the caller
219 1.1 cgd * is root or the caller isn't changing their uid, don't
220 1.1 cgd * authenticate.
221 1.1 cgd */
222 1.1 cgd if (pwd && (*pwd->pw_passwd == '\0' ||
223 1.1 cgd fflag && (uid == 0 || uid == pwd->pw_uid)))
224 1.1 cgd break;
225 1.1 cgd fflag = 0;
226 1.1 cgd if (pwd && pwd->pw_uid == 0)
227 1.1 cgd rootlogin = 1;
228 1.1 cgd
229 1.1 cgd (void)setpriority(PRIO_PROCESS, 0, -4);
230 1.1 cgd
231 1.1 cgd p = getpass("Password:");
232 1.1 cgd
233 1.1 cgd if (pwd) {
234 1.1 cgd #ifdef KERBEROS
235 1.1 cgd rval = klogin(pwd, instance, localhost, p);
236 1.1 cgd if (rval == 0)
237 1.1 cgd authok = 1;
238 1.1 cgd else if (rval == 1) {
239 1.1 cgd if (pwd->pw_uid != 0)
240 1.1 cgd rootlogin = 0;
241 1.1 cgd rval = strcmp(crypt(p, salt), pwd->pw_passwd);
242 1.1 cgd }
243 1.1 cgd #else
244 1.1 cgd if (pwd->pw_uid != 0)
245 1.1 cgd rootlogin = 0;
246 1.1 cgd #ifdef DES
247 1.1 cgd rval = strcmp(crypt(p, salt), pwd->pw_passwd);
248 1.1 cgd #else
249 1.1 cgd rval = strcmp(p, pwd->pw_passwd);
250 1.1 cgd #endif
251 1.1 cgd #endif
252 1.1 cgd }
253 1.1 cgd bzero(p, strlen(p));
254 1.1 cgd
255 1.1 cgd (void)setpriority(PRIO_PROCESS, 0, 0);
256 1.1 cgd
257 1.1 cgd /*
258 1.1 cgd * If trying to log in as root without Kerberos,
259 1.1 cgd * but with insecure terminal, refuse the login attempt.
260 1.1 cgd */
261 1.1 cgd #ifdef KERBEROS
262 1.1 cgd if (authok == 0)
263 1.1 cgd #endif
264 1.1 cgd if (pwd && rootlogin && !rootterm(tty)) {
265 1.1 cgd (void)fprintf(stderr,
266 1.1 cgd "%s login refused on this terminal.\n",
267 1.1 cgd pwd->pw_name);
268 1.1 cgd if (hostname)
269 1.1 cgd syslog(LOG_NOTICE,
270 1.1 cgd "LOGIN %s REFUSED FROM %s ON TTY %s",
271 1.1 cgd pwd->pw_name, hostname, tty);
272 1.1 cgd else
273 1.1 cgd syslog(LOG_NOTICE,
274 1.1 cgd "LOGIN %s REFUSED ON TTY %s",
275 1.1 cgd pwd->pw_name, tty);
276 1.1 cgd continue;
277 1.1 cgd }
278 1.1 cgd
279 1.1 cgd if (pwd && !rval)
280 1.1 cgd break;
281 1.1 cgd
282 1.1 cgd (void)printf("Login incorrect\n");
283 1.1 cgd failures++;
284 1.1 cgd /* we allow 10 tries, but after 3 we start backing off */
285 1.1 cgd if (++cnt > 3) {
286 1.1 cgd if (cnt >= 10) {
287 1.1 cgd badlogin(username);
288 1.1 cgd sleepexit(1);
289 1.1 cgd }
290 1.1 cgd sleep((u_int)((cnt - 3) * 5));
291 1.1 cgd }
292 1.1 cgd }
293 1.1 cgd
294 1.1 cgd /* committed to login -- turn off timeout */
295 1.1 cgd (void)alarm((u_int)0);
296 1.1 cgd
297 1.1 cgd endpwent();
298 1.1 cgd
299 1.1 cgd /* if user not super-user, check for disabled logins */
300 1.1 cgd if (!rootlogin)
301 1.1 cgd checknologin();
302 1.1 cgd
303 1.1 cgd if (chdir(pwd->pw_dir) < 0) {
304 1.1 cgd (void)printf("No home directory %s!\n", pwd->pw_dir);
305 1.1 cgd if (chdir("/"))
306 1.1 cgd exit(0);
307 1.1 cgd pwd->pw_dir = "/";
308 1.1 cgd (void)printf("Logging in with home = \"/\".\n");
309 1.1 cgd }
310 1.1 cgd
311 1.1 cgd quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
312 1.1 cgd
313 1.1 cgd if (pwd->pw_change || pwd->pw_expire)
314 1.1 cgd (void)gettimeofday(&tp, (struct timezone *)NULL);
315 1.1 cgd if (pwd->pw_change)
316 1.1 cgd if (tp.tv_sec >= pwd->pw_change) {
317 1.1 cgd (void)printf("Sorry -- your password has expired.\n");
318 1.1 cgd sleepexit(1);
319 1.1 cgd } else if (pwd->pw_change - tp.tv_sec <
320 1.1 cgd 2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
321 1.1 cgd (void)printf("Warning: your password expires on %s",
322 1.1 cgd ctime(&pwd->pw_expire));
323 1.1 cgd if (pwd->pw_expire)
324 1.1 cgd if (tp.tv_sec >= pwd->pw_expire) {
325 1.1 cgd (void)printf("Sorry -- your account has expired.\n");
326 1.1 cgd sleepexit(1);
327 1.1 cgd } else if (pwd->pw_expire - tp.tv_sec <
328 1.1 cgd 2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
329 1.1 cgd (void)printf("Warning: your account expires on %s",
330 1.1 cgd ctime(&pwd->pw_expire));
331 1.1 cgd
332 1.1 cgd /* nothing else left to fail -- really log in */
333 1.1 cgd {
334 1.1 cgd struct utmp utmp;
335 1.1 cgd
336 1.1 cgd bzero((void *)&utmp, sizeof(utmp));
337 1.1 cgd (void)time(&utmp.ut_time);
338 1.1 cgd strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
339 1.1 cgd if (hostname)
340 1.1 cgd strncpy(utmp.ut_host, hostname, sizeof(utmp.ut_host));
341 1.1 cgd strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
342 1.1 cgd login(&utmp);
343 1.1 cgd }
344 1.1 cgd
345 1.1 cgd dolastlog(quietlog);
346 1.1 cgd
347 1.1 cgd (void)chown(ttyn, pwd->pw_uid,
348 1.1 cgd (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
349 1.1 cgd (void)setgid(pwd->pw_gid);
350 1.1 cgd
351 1.1 cgd initgroups(username, pwd->pw_gid);
352 1.1 cgd
353 1.1 cgd if (*pwd->pw_shell == '\0')
354 1.1 cgd pwd->pw_shell = _PATH_BSHELL;
355 1.1 cgd
356 1.1 cgd /* destroy environment unless user has requested preservation */
357 1.1 cgd if (!pflag)
358 1.1 cgd environ = envinit;
359 1.1 cgd (void)setenv("HOME", pwd->pw_dir, 1);
360 1.1 cgd (void)setenv("SHELL", pwd->pw_shell, 1);
361 1.1 cgd if (term[0] == '\0')
362 1.1 cgd strncpy(term, stypeof(tty), sizeof(term));
363 1.1 cgd (void)setenv("TERM", term, 0);
364 1.1 cgd (void)setenv("LOGNAME", pwd->pw_name, 1);
365 1.1 cgd (void)setenv("USER", pwd->pw_name, 1);
366 1.1 cgd (void)setenv("PATH", _PATH_DEFPATH, 0);
367 1.1 cgd #ifdef KERBEROS
368 1.1 cgd if (krbtkfile_env)
369 1.1 cgd (void)setenv("KRBTKFILE", krbtkfile_env, 1);
370 1.1 cgd #endif
371 1.1 cgd
372 1.1 cgd if (tty[sizeof("tty")-1] == 'd')
373 1.1 cgd syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
374 1.1 cgd /* if fflag is on, assume caller/authenticator has logged root login */
375 1.1 cgd if (rootlogin && fflag == 0)
376 1.1 cgd if (hostname)
377 1.1 cgd syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
378 1.1 cgd username, tty, hostname);
379 1.1 cgd else
380 1.1 cgd syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty);
381 1.1 cgd
382 1.1 cgd #ifdef KERBEROS
383 1.1 cgd if (!quietlog && notickets == 1)
384 1.1 cgd (void)printf("Warning: no Kerberos tickets issued.\n");
385 1.1 cgd #endif
386 1.1 cgd
387 1.1 cgd if (!quietlog) {
388 1.1 cgd struct stat st;
389 1.1 cgd
390 1.1 cgd printf("%s%s",
391 1.1 cgd "386BSD Release 0.1 by William and Lynne Jolitz.\n",
392 1.1 cgd "Copyright (c) 1989,1990,1991,1992 William F. Jolitz. All rights reserved.\n\
393 1.1 cgd Based in part on work by the 386BSD User Community and the\n\
394 1.1 cgd BSD Networking Software, Release 2 by UCB EECS Department.\n");
395 1.1 cgd
396 1.1 cgd motd();
397 1.1 cgd (void)sprintf(tbuf, "%s/%s", _PATH_MAILDIR, pwd->pw_name);
398 1.1 cgd if (stat(tbuf, &st) == 0 && st.st_size != 0)
399 1.1 cgd (void)printf("You have %smail.\n",
400 1.1 cgd (st.st_mtime > st.st_atime) ? "new " : "");
401 1.1 cgd }
402 1.1 cgd
403 1.1 cgd (void)signal(SIGALRM, SIG_DFL);
404 1.1 cgd (void)signal(SIGQUIT, SIG_DFL);
405 1.1 cgd (void)signal(SIGINT, SIG_DFL);
406 1.1 cgd (void)signal(SIGTSTP, SIG_IGN);
407 1.1 cgd
408 1.1 cgd tbuf[0] = '-';
409 1.1 cgd strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ?
410 1.1 cgd p + 1 : pwd->pw_shell);
411 1.1 cgd
412 1.1 cgd if (setlogin(pwd->pw_name) < 0)
413 1.1 cgd syslog(LOG_ERR, "setlogin() failure: %m");
414 1.1 cgd
415 1.1 cgd /* discard permissions last so can't get killed and drop core */
416 1.1 cgd if (rootlogin)
417 1.1 cgd (void) setuid(0);
418 1.1 cgd else
419 1.1 cgd (void) setuid(pwd->pw_uid);
420 1.1 cgd
421 1.1 cgd execlp(pwd->pw_shell, tbuf, 0);
422 1.1 cgd (void)fprintf(stderr, "%s: %s\n", pwd->pw_shell, strerror(errno));
423 1.1 cgd exit(1);
424 1.1 cgd }
425 1.1 cgd
426 1.1 cgd #ifdef KERBEROS
427 1.1 cgd #define NBUFSIZ (UT_NAMESIZE + 1 + 5) /* .root suffix */
428 1.1 cgd #else
429 1.1 cgd #define NBUFSIZ (UT_NAMESIZE + 1)
430 1.1 cgd #endif
431 1.1 cgd
432 1.1 cgd getloginname()
433 1.1 cgd {
434 1.1 cgd register int ch;
435 1.1 cgd register char *p;
436 1.1 cgd static char nbuf[NBUFSIZ];
437 1.1 cgd
438 1.1 cgd for (;;) {
439 1.1 cgd (void)printf("login: ");
440 1.1 cgd for (p = nbuf; (ch = getchar()) != '\n'; ) {
441 1.1 cgd if (ch == EOF) {
442 1.1 cgd badlogin(username);
443 1.1 cgd exit(0);
444 1.1 cgd }
445 1.1 cgd if (p < nbuf + (NBUFSIZ - 1))
446 1.1 cgd *p++ = ch;
447 1.1 cgd }
448 1.1 cgd if (p > nbuf)
449 1.1 cgd if (nbuf[0] == '-')
450 1.1 cgd (void)fprintf(stderr,
451 1.1 cgd "login names may not start with '-'.\n");
452 1.1 cgd else {
453 1.1 cgd *p = '\0';
454 1.1 cgd username = nbuf;
455 1.1 cgd break;
456 1.1 cgd }
457 1.1 cgd }
458 1.1 cgd }
459 1.1 cgd
460 1.1 cgd void
461 1.1 cgd timedout()
462 1.1 cgd {
463 1.1 cgd (void)fprintf(stderr, "Login timed out after %d seconds\n", timeout);
464 1.1 cgd exit(0);
465 1.1 cgd }
466 1.1 cgd
467 1.1 cgd rootterm(ttyn)
468 1.1 cgd char *ttyn;
469 1.1 cgd {
470 1.1 cgd struct ttyent *t;
471 1.1 cgd
472 1.1 cgd return((t = getttynam(ttyn)) && t->ty_status&TTY_SECURE);
473 1.1 cgd }
474 1.1 cgd
475 1.1 cgd jmp_buf motdinterrupt;
476 1.1 cgd
477 1.1 cgd motd()
478 1.1 cgd {
479 1.1 cgd register int fd, nchars;
480 1.1 cgd sig_t oldint;
481 1.1 cgd void sigint();
482 1.1 cgd char tbuf[8192];
483 1.1 cgd
484 1.1 cgd if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)
485 1.1 cgd return;
486 1.1 cgd oldint = signal(SIGINT, sigint);
487 1.1 cgd if (setjmp(motdinterrupt) == 0)
488 1.1 cgd while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
489 1.1 cgd (void)write(fileno(stdout), tbuf, nchars);
490 1.1 cgd (void)signal(SIGINT, oldint);
491 1.1 cgd (void)close(fd);
492 1.1 cgd }
493 1.1 cgd
494 1.1 cgd void
495 1.1 cgd sigint()
496 1.1 cgd {
497 1.1 cgd longjmp(motdinterrupt, 1);
498 1.1 cgd }
499 1.1 cgd
500 1.1 cgd checknologin()
501 1.1 cgd {
502 1.1 cgd register int fd, nchars;
503 1.1 cgd char tbuf[8192];
504 1.1 cgd
505 1.1 cgd if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
506 1.1 cgd while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
507 1.1 cgd (void)write(fileno(stdout), tbuf, nchars);
508 1.1 cgd sleepexit(0);
509 1.1 cgd }
510 1.1 cgd }
511 1.1 cgd
512 1.1 cgd dolastlog(quiet)
513 1.1 cgd int quiet;
514 1.1 cgd {
515 1.1 cgd struct lastlog ll;
516 1.1 cgd int fd;
517 1.1 cgd char *ctime();
518 1.1 cgd
519 1.1 cgd if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
520 1.1 cgd (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
521 1.1 cgd if (!quiet) {
522 1.1 cgd if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
523 1.1 cgd ll.ll_time != 0) {
524 1.1 cgd (void)printf("Last login: %.*s ",
525 1.1 cgd 24-5, (char *)ctime(&ll.ll_time));
526 1.1 cgd if (*ll.ll_host != '\0')
527 1.1 cgd (void)printf("from %.*s\n",
528 1.1 cgd sizeof(ll.ll_host), ll.ll_host);
529 1.1 cgd else
530 1.1 cgd (void)printf("on %.*s\n",
531 1.1 cgd sizeof(ll.ll_line), ll.ll_line);
532 1.1 cgd }
533 1.1 cgd (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
534 1.1 cgd }
535 1.1 cgd bzero((void *)&ll, sizeof(ll));
536 1.1 cgd (void)time(&ll.ll_time);
537 1.1 cgd strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
538 1.1 cgd if (hostname)
539 1.1 cgd strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
540 1.1 cgd (void)write(fd, (char *)&ll, sizeof(ll));
541 1.1 cgd (void)close(fd);
542 1.1 cgd }
543 1.1 cgd }
544 1.1 cgd
545 1.1 cgd badlogin(name)
546 1.1 cgd char *name;
547 1.1 cgd {
548 1.1 cgd if (failures == 0)
549 1.1 cgd return;
550 1.1 cgd if (hostname) {
551 1.1 cgd syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s",
552 1.1 cgd failures, failures > 1 ? "S" : "", hostname);
553 1.1 cgd syslog(LOG_AUTHPRIV|LOG_NOTICE,
554 1.1 cgd "%d LOGIN FAILURE%s FROM %s, %s",
555 1.1 cgd failures, failures > 1 ? "S" : "", hostname, name);
556 1.1 cgd } else {
557 1.1 cgd syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s",
558 1.1 cgd failures, failures > 1 ? "S" : "", tty);
559 1.1 cgd syslog(LOG_AUTHPRIV|LOG_NOTICE,
560 1.1 cgd "%d LOGIN FAILURE%s ON %s, %s",
561 1.1 cgd failures, failures > 1 ? "S" : "", tty, name);
562 1.1 cgd }
563 1.1 cgd }
564 1.1 cgd
565 1.1 cgd #undef UNKNOWN
566 1.1 cgd #define UNKNOWN "su"
567 1.1 cgd
568 1.1 cgd char *
569 1.1 cgd stypeof(ttyid)
570 1.1 cgd char *ttyid;
571 1.1 cgd {
572 1.1 cgd struct ttyent *t;
573 1.1 cgd
574 1.1 cgd return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
575 1.1 cgd }
576 1.1 cgd
577 1.1 cgd sleepexit(eval)
578 1.1 cgd int eval;
579 1.1 cgd {
580 1.1 cgd sleep((u_int)5);
581 1.1 cgd exit(eval);
582 1.1 cgd }
583