blob: ff41845729976e3c4a5bf68db2f48cbb1c281072 [file] [log] [blame]
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001/*
Damien Miller95def091999-11-25 00:26:21 +11002 *
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 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100019
20#include "includes.h"
Damien Millerbf1c9b21999-12-09 10:16:54 +110021RCSID("$Id: login.c,v 1.6 1999/12/08 23:16:55 damien Exp $");
Damien Millerd4a8b7e1999-10-27 13:42:43 +100022
Damien Millerbf1c9b21999-12-09 10:16:54 +110023#ifdef HAVE_UTMPX_H
24# include <utmpx.h>
25#endif
26#ifdef HAVE_UTMP_H
27# include <utmp.h>
28#endif
Damien Miller95def091999-11-25 00:26:21 +110029#include "ssh.h"
Damien Millerab18c411999-11-11 10:40:23 +110030
Damien Miller95def091999-11-25 00:26:21 +110031#ifdef HAVE_UTIL_H
32# include <util.h>
33#endif
Damien Millerab18c411999-11-11 10:40:23 +110034#ifdef HAVE_LASTLOG_H
35# include <lastlog.h>
36#endif
Damien Miller063fdf81999-11-25 13:08:31 +110037#ifdef HAVE_LOGIN_H
38# include <login.h>
39#endif
Damien Millerab18c411999-11-11 10:40:23 +110040
Damien Miller5428f641999-11-25 11:54:57 +110041/*
42 * Returns the time when the user last logged in. Returns 0 if the
43 * information is not available. This must be called before record_login.
44 * The host the user logged in from will be returned in buf.
45 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100046
Damien Miller5428f641999-11-25 11:54:57 +110047/*
48 * Returns the time when the user last logged in (or 0 if no previous login
49 * is found). The name of the host used last time is returned in buf.
50 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100051
Damien Miller95def091999-11-25 00:26:21 +110052unsigned long
53get_last_login_time(uid_t uid, const char *logname,
54 char *buf, unsigned int bufsize)
Damien Millerd4a8b7e1999-10-27 13:42:43 +100055{
Damien Miller95def091999-11-25 00:26:21 +110056 struct lastlog ll;
57 char *lastlog;
58 int fd;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100059
Damien Miller95def091999-11-25 00:26:21 +110060 lastlog = _PATH_LASTLOG;
61 buf[0] = '\0';
Damien Millerd4a8b7e1999-10-27 13:42:43 +100062
Damien Miller95def091999-11-25 00:26:21 +110063 fd = open(lastlog, O_RDONLY);
64 if (fd < 0)
65 return 0;
66 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
67 if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) {
68 close(fd);
69 return 0;
70 }
71 close(fd);
72 if (bufsize > sizeof(ll.ll_host) + 1)
73 bufsize = sizeof(ll.ll_host) + 1;
74 strncpy(buf, ll.ll_host, bufsize - 1);
75 buf[bufsize - 1] = 0;
76 return ll.ll_time;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100077}
78
Damien Miller5428f641999-11-25 11:54:57 +110079/*
80 * Records that the user has logged in. I these parts of operating systems
81 * were more standardized.
82 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100083
Damien Miller95def091999-11-25 00:26:21 +110084void
85record_login(int pid, const char *ttyname, const char *user, uid_t uid,
86 const char *host, struct sockaddr_in * addr)
Damien Millerd4a8b7e1999-10-27 13:42:43 +100087{
Damien Miller95def091999-11-25 00:26:21 +110088 int fd;
89 struct lastlog ll;
90 char *lastlog;
Damien Millerbf1c9b21999-12-09 10:16:54 +110091 struct UTMP_STR u;
Damien Miller95def091999-11-25 00:26:21 +110092 const char *utmp, *wtmp;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100093
Damien Miller95def091999-11-25 00:26:21 +110094 /* Construct an utmp/wtmp entry. */
95 memset(&u, 0, sizeof(u));
96 strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
Damien Millerbf1c9b21999-12-09 10:16:54 +110097#ifdef HAVE_UTMPX_H
98 u.ut_tv.tv_sec = time(NULL);
99 strncpy(u.ut_user, user, sizeof(u.ut_name));
100#else
Damien Miller95def091999-11-25 00:26:21 +1100101 u.ut_time = time(NULL);
102 strncpy(u.ut_name, user, sizeof(u.ut_name));
Damien Millerbf1c9b21999-12-09 10:16:54 +1100103#endif
104#if defined(HAVE_HOST_IN_UTMP) || defined(HAVE_HOST_IN_UTMPX)
Damien Miller95def091999-11-25 00:26:21 +1100105 strncpy(u.ut_host, host, sizeof(u.ut_host));
Damien Millerab18c411999-11-11 10:40:23 +1100106#endif
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000107
Damien Miller95def091999-11-25 00:26:21 +1100108 /* Figure out the file names. */
109 utmp = _PATH_UTMP;
110 wtmp = _PATH_WTMP;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000111
Damien Miller95def091999-11-25 00:26:21 +1100112 login(&u);
113 lastlog = _PATH_LASTLOG;
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000114
Damien Miller95def091999-11-25 00:26:21 +1100115 /* Update lastlog unless actually recording a logout. */
116 if (strcmp(user, "") != 0) {
Damien Miller5428f641999-11-25 11:54:57 +1100117 /*
118 * It is safer to bzero the lastlog structure first because
119 * some systems might have some extra fields in it (e.g. SGI)
120 */
Damien Miller95def091999-11-25 00:26:21 +1100121 memset(&ll, 0, sizeof(ll));
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000122
Damien Miller95def091999-11-25 00:26:21 +1100123 /* Update lastlog. */
124 ll.ll_time = time(NULL);
125 strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
126 strncpy(ll.ll_host, host, sizeof(ll.ll_host));
127 fd = open(lastlog, O_RDWR);
128 if (fd >= 0) {
129 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
130 if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
131 log("Could not write %.100s: %.100s", lastlog, strerror(errno));
132 close(fd);
133 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000134 }
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000135}
Damien Miller95def091999-11-25 00:26:21 +1100136
137/* Records that the user has logged out. */
138
139void
140record_logout(int pid, const char *ttyname)
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000141{
Damien Millerab18c411999-11-11 10:40:23 +1100142#ifdef HAVE_LIBUTIL_LOGIN
Damien Miller95def091999-11-25 00:26:21 +1100143 const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */
144 if (logout(line))
145 logwtmp(line, "", "");
Damien Millerab18c411999-11-11 10:40:23 +1100146#else /* HAVE_LIBUTIL_LOGIN */
Damien Miller95def091999-11-25 00:26:21 +1100147 record_login(pid, ttyname, "", -1, "", NULL);
Damien Millerab18c411999-11-11 10:40:23 +1100148#endif /* HAVE_LIBUTIL_LOGIN */
Damien Millerd4a8b7e1999-10-27 13:42:43 +1000149}