Annotation of src/usr.bin/ssh/login.c, Revision 1.8
1.1 deraadt 1: /*
2:
3: login.c
4:
5: Author: Tatu Ylonen <ylo@cs.hut.fi>
6:
7: Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8: All rights reserved
9:
10: Created: Fri Mar 24 14:51:08 1995 ylo
11:
12: This file performs some of the things login(1) normally does. We cannot
13: easily use something like login -p -h host -f user, because there are
14: several different logins around, and it is hard to determined what kind of
15: login the current system has. Also, we want to be able to execute commands
16: on a tty.
17:
18: */
19:
20: #include "includes.h"
1.8 ! markus 21: RCSID("$Id: login.c,v 1.7 1999/09/30 16:55:06 deraadt Exp $");
1.1 deraadt 22:
1.2 dugsong 23: #include <util.h>
1.1 deraadt 24: #include <utmp.h>
25: #include "ssh.h"
26:
1.8 ! markus 27: /* Returns the time when the user last logged in. Returns 0 if the
! 28: information is not available. This must be called before record_login.
1.1 deraadt 29: The host the user logged in from will be returned in buf. */
30:
31: /* Returns the time when the user last logged in (or 0 if no previous login
32: is found). The name of the host used last time is returned in buf. */
33:
1.8 ! markus 34: unsigned long
! 35: get_last_login_time(uid_t uid, const char *logname,
! 36: char *buf, unsigned int bufsize)
1.1 deraadt 37: {
1.8 ! markus 38: struct lastlog ll;
! 39: char *lastlog;
! 40: int fd;
! 41:
! 42: lastlog = _PATH_LASTLOG;
! 43: buf[0] = '\0';
! 44:
! 45: fd = open(lastlog, O_RDONLY);
! 46: if (fd < 0)
! 47: return 0;
! 48: lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
! 49: if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) {
! 50: close(fd);
! 51: return 0;
! 52: }
! 53: close(fd);
! 54: if (bufsize > sizeof(ll.ll_host) + 1)
! 55: bufsize = sizeof(ll.ll_host) + 1;
! 56: strncpy(buf, ll.ll_host, bufsize - 1);
! 57: buf[bufsize - 1] = 0;
! 58: return ll.ll_time;
1.1 deraadt 59: }
60:
61: /* Records that the user has logged in. I these parts of operating systems
62: were more standardized. */
63:
1.8 ! markus 64: void
! 65: record_login(int pid, const char *ttyname, const char *user, uid_t uid,
! 66: const char *host, struct sockaddr_in * addr)
1.1 deraadt 67: {
1.8 ! markus 68: int fd;
! 69: struct lastlog ll;
! 70: char *lastlog;
! 71: struct utmp u;
! 72: const char *utmp, *wtmp;
! 73:
! 74: /* Construct an utmp/wtmp entry. */
! 75: memset(&u, 0, sizeof(u));
! 76: strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
! 77: u.ut_time = time(NULL);
! 78: strncpy(u.ut_name, user, sizeof(u.ut_name));
! 79: strncpy(u.ut_host, host, sizeof(u.ut_host));
! 80:
! 81: /* Figure out the file names. */
! 82: utmp = _PATH_UTMP;
! 83: wtmp = _PATH_WTMP;
! 84:
! 85: login(&u);
! 86: lastlog = _PATH_LASTLOG;
! 87:
! 88: /* Update lastlog unless actually recording a logout. */
! 89: if (strcmp(user, "") != 0) {
! 90: /* It is safer to bzero the lastlog structure first
! 91: because some systems might have some extra fields in it
! 92: (e.g. SGI) */
! 93: memset(&ll, 0, sizeof(ll));
! 94:
! 95: /* Update lastlog. */
! 96: ll.ll_time = time(NULL);
! 97: strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
! 98: strncpy(ll.ll_host, host, sizeof(ll.ll_host));
! 99: fd = open(lastlog, O_RDWR);
! 100: if (fd >= 0) {
! 101: lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
! 102: if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
! 103: log("Could not write %.100s: %.100s", lastlog, strerror(errno));
! 104: close(fd);
! 105: }
1.1 deraadt 106: }
107: }
1.8 ! markus 108:
1.1 deraadt 109: /* Records that the user has logged out. */
110:
1.8 ! markus 111: void
! 112: record_logout(int pid, const char *ttyname)
1.1 deraadt 113: {
1.8 ! markus 114: const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */
! 115: if (logout(line))
! 116: logwtmp(line, "", "");
1.1 deraadt 117: }