]> andersk Git - openssh.git/blame - login.c
- Prepare for 1.2.1pre20
[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) */
f498ed15 136 struct utmp u;
137#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
138 struct utmpx utx;
139#endif
5260325f 140
141 /* Construct an utmp/wtmp entry. */
142 memset(&u, 0, sizeof(u));
143 strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
f498ed15 144 u.ut_pid = (pid_t)pid;
5260325f 145 u.ut_time = time(NULL);
146 strncpy(u.ut_name, user, sizeof(u.ut_name));
f498ed15 147 u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS;
148#if defined(HAVE_HOST_IN_UTMP)
5260325f 149 strncpy(u.ut_host, host, sizeof(u.ut_host));
4cca272e 150#endif
8efc0c15 151
f498ed15 152#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
153 memset(&utx, 0, sizeof(utx));
154 strncpy(utx.ut_user, user, sizeof(utx.ut_name));
155 strncpy(utx.ut_line, ttyname + 5, sizeof(utx.ut_line));
156 utx.ut_pid = (pid_t)pid;
157 utx.ut_tv.tv_sec = time(NULL);
158 u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS;
159#ifdef HAVE_HOST_IN_UTMPX
160#ifdef HAVE_SYSLEN_IN_UTMPX
161 utx.ut_syslen = strlen(host);
162 strncpy(utx.ut_host, host, utx.ut_syslen );
163#else
164 strncpy(utx.ut_host, host, sizeof(utx.ut_host));
165#endif /* HAVE_SYSLEN_IN_UTMPX */
166#endif
167#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
5260325f 168
f498ed15 169#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) && !defined(HAVE_LOGIN)
170 login(&u, &utx);
171#else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
5260325f 172 login(&u);
f498ed15 173#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
a7effaac 174
ae28776a 175#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
5260325f 176 lastlog = _PATH_LASTLOG;
177
178 /* Update lastlog unless actually recording a logout. */
179 if (strcmp(user, "") != 0) {
a7effaac 180 int fd;
aa3378df 181 /*
182 * It is safer to bzero the lastlog structure first because
183 * some systems might have some extra fields in it (e.g. SGI)
184 */
5260325f 185 memset(&ll, 0, sizeof(ll));
186
187 /* Update lastlog. */
188 ll.ll_time = time(NULL);
189 strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
190 strncpy(ll.ll_host, host, sizeof(ll.ll_host));
191 fd = open(lastlog, O_RDWR);
192 if (fd >= 0) {
193 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
194 if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
195 log("Could not write %.100s: %.100s", lastlog, strerror(errno));
196 close(fd);
197 }
8efc0c15 198 }
ae28776a 199#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
8efc0c15 200}
5260325f 201
202/* Records that the user has logged out. */
203
204void
205record_logout(int pid, const char *ttyname)
8efc0c15 206{
4cca272e 207#ifdef HAVE_LIBUTIL_LOGIN
5260325f 208 const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */
209 if (logout(line))
210 logwtmp(line, "", "");
4cca272e 211#else /* HAVE_LIBUTIL_LOGIN */
5260325f 212 record_login(pid, ttyname, "", -1, "", NULL);
4cca272e 213#endif /* HAVE_LIBUTIL_LOGIN */
8efc0c15 214}
This page took 0.081974 seconds and 5 git commands to generate.