]> andersk Git - openssh.git/blame - login.c
- Fix login.c breakage on systems which lack ut_host in struct
[openssh.git] / login.c
CommitLineData
8efc0c15 1/*
5260325f 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 */
8efc0c15 19
20#include "includes.h"
21RCSID("$Id$");
22
92f90c57 23#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
8946db53 24# include <utmpx.h>
25#endif
26#ifdef HAVE_UTMP_H
27# include <utmp.h>
28#endif
5260325f 29#include "ssh.h"
4cca272e 30
5260325f 31#ifdef HAVE_UTIL_H
32# include <util.h>
33#endif
4cca272e 34#ifdef HAVE_LASTLOG_H
35# include <lastlog.h>
36#endif
09041313 37#ifdef HAVE_LOGIN_H
38# include <login.h>
39#endif
4cca272e 40
aa3378df 41/*
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 */
8efc0c15 46
aa3378df 47/*
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 */
8efc0c15 51
5260325f 52unsigned long
53get_last_login_time(uid_t uid, const char *logname,
54 char *buf, unsigned int bufsize)
8efc0c15 55{
ae28776a 56#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
5260325f 57 struct lastlog ll;
58 char *lastlog;
59 int fd;
60
61 lastlog = _PATH_LASTLOG;
62 buf[0] = '\0';
63
64 fd = open(lastlog, O_RDONLY);
65 if (fd < 0)
66 return 0;
67 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
68 if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) {
69 close(fd);
70 return 0;
71 }
72 close(fd);
73 if (bufsize > sizeof(ll.ll_host) + 1)
74 bufsize = sizeof(ll.ll_host) + 1;
75 strncpy(buf, ll.ll_host, bufsize - 1);
76 buf[bufsize - 1] = 0;
77 return ll.ll_time;
a7effaac 78
ae28776a 79#else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
a7effaac 80 /* Look in wtmp for the last login */
81 struct utmp wt;
82 char *wt_file = _PATH_WTMP;
83 int fd1;
84 unsigned long t = 0;
85
86 if ( (fd1 = open(wt_file, O_RDONLY)) < 0 ) {
87 error("Couldn't open %.100s to find last login time.", wt_file);
88 return 0;
89 }
90
91 /* seek to last record of file */
92 lseek(fd1, (off_t)(0-sizeof(struct utmp)), SEEK_END);
93
94 /* loop through wtmp for our last user login record */
95 do {
96 if (read(fd1, &wt, sizeof(wt)) != sizeof(wt)) {
97 close(fd1);
98 return 0;
99 }
100
101 if ( wt.ut_type == USER_PROCESS) {
102 if ( !strncmp(logname, wt.ut_user, 8) ) {
103 t = (unsigned long) wt.ut_time;
ae28776a 104#ifdef HAVE_HOST_IN_UTMP
a7effaac 105 if (bufsize > sizeof(wt.ut_host) + 1)
106 bufsize = sizeof(wt.ut_host) + 1;
107 strncpy(buf, wt.ut_host, bufsize - 1);
108 buf[bufsize - 1] = 0;
ae28776a 109#else /* HAVE_HOST_IN_UTMP */
110 buf[0] = 0;
111#endif /* HAVE_HOST_IN_UTMP */
a7effaac 112 }
113 }
114
115 if (lseek(fd1, (off_t)(0-2*sizeof(struct utmp)), SEEK_CUR) == -1)
116 break;
117 } while (t == 0);
118
119 return t;
ae28776a 120#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
8efc0c15 121}
122
aa3378df 123/*
124 * Records that the user has logged in. I these parts of operating systems
125 * were more standardized.
126 */
8efc0c15 127
5260325f 128void
129record_login(int pid, const char *ttyname, const char *user, uid_t uid,
130 const char *host, struct sockaddr_in * addr)
8efc0c15 131{
ae28776a 132#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
5260325f 133 struct lastlog ll;
134 char *lastlog;
ae28776a 135#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
8946db53 136 struct UTMP_STR u;
5260325f 137 const char *utmp, *wtmp;
138
139 /* Construct an utmp/wtmp entry. */
140 memset(&u, 0, sizeof(u));
141 strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
92f90c57 142#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
8946db53 143 u.ut_tv.tv_sec = time(NULL);
144 strncpy(u.ut_user, user, sizeof(u.ut_name));
145#else
5260325f 146 u.ut_time = time(NULL);
147 strncpy(u.ut_name, user, sizeof(u.ut_name));
8946db53 148#endif
149#if defined(HAVE_HOST_IN_UTMP) || defined(HAVE_HOST_IN_UTMPX)
5260325f 150 strncpy(u.ut_host, host, sizeof(u.ut_host));
4cca272e 151#endif
8efc0c15 152
5260325f 153 /* Figure out the file names. */
154 utmp = _PATH_UTMP;
155 wtmp = _PATH_WTMP;
156
157 login(&u);
a7effaac 158
ae28776a 159#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
5260325f 160 lastlog = _PATH_LASTLOG;
161
162 /* Update lastlog unless actually recording a logout. */
163 if (strcmp(user, "") != 0) {
a7effaac 164 int fd;
aa3378df 165 /*
166 * It is safer to bzero the lastlog structure first because
167 * some systems might have some extra fields in it (e.g. SGI)
168 */
5260325f 169 memset(&ll, 0, sizeof(ll));
170
171 /* Update lastlog. */
172 ll.ll_time = time(NULL);
173 strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
174 strncpy(ll.ll_host, host, sizeof(ll.ll_host));
175 fd = open(lastlog, O_RDWR);
176 if (fd >= 0) {
177 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
178 if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
179 log("Could not write %.100s: %.100s", lastlog, strerror(errno));
180 close(fd);
181 }
8efc0c15 182 }
ae28776a 183#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
8efc0c15 184}
5260325f 185
186/* Records that the user has logged out. */
187
188void
189record_logout(int pid, const char *ttyname)
8efc0c15 190{
4cca272e 191#ifdef HAVE_LIBUTIL_LOGIN
5260325f 192 const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */
193 if (logout(line))
194 logwtmp(line, "", "");
4cca272e 195#else /* HAVE_LIBUTIL_LOGIN */
5260325f 196 record_login(pid, ttyname, "", -1, "", NULL);
4cca272e 197#endif /* HAVE_LIBUTIL_LOGIN */
8efc0c15 198}
This page took 0.459062 seconds and 5 git commands to generate.