]> andersk Git - openssh.git/blame - login.c
- Integration of large HPUX patch from Andre Lucas
[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{
a7effaac 56#if defined(HAVE_LASTLOG_H) && !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
79#else /* defined(HAVE_LASTLOG_H) && !defined(DISABLE_LASTLOG) */
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;
104 if (bufsize > sizeof(wt.ut_host) + 1)
105 bufsize = sizeof(wt.ut_host) + 1;
106 strncpy(buf, wt.ut_host, bufsize - 1);
107 buf[bufsize - 1] = 0;
108 }
109 }
110
111 if (lseek(fd1, (off_t)(0-2*sizeof(struct utmp)), SEEK_CUR) == -1)
112 break;
113 } while (t == 0);
114
115 return t;
116#endif /* defined(HAVE_LASTLOG_H) && !defined(DISABLE_LASTLOG) */
8efc0c15 117}
118
aa3378df 119/*
120 * Records that the user has logged in. I these parts of operating systems
121 * were more standardized.
122 */
8efc0c15 123
5260325f 124void
125record_login(int pid, const char *ttyname, const char *user, uid_t uid,
126 const char *host, struct sockaddr_in * addr)
8efc0c15 127{
a7effaac 128#if defined(HAVE_LASTLOG_H) && !defined(DISABLE_LASTLOG)
5260325f 129 struct lastlog ll;
130 char *lastlog;
a7effaac 131#endif /* defined(HAVE_LASTLOG_H) && !defined(DISABLE_LASTLOG) */
8946db53 132 struct UTMP_STR u;
5260325f 133 const char *utmp, *wtmp;
134
135 /* Construct an utmp/wtmp entry. */
136 memset(&u, 0, sizeof(u));
137 strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
92f90c57 138#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
8946db53 139 u.ut_tv.tv_sec = time(NULL);
140 strncpy(u.ut_user, user, sizeof(u.ut_name));
141#else
5260325f 142 u.ut_time = time(NULL);
143 strncpy(u.ut_name, user, sizeof(u.ut_name));
8946db53 144#endif
145#if defined(HAVE_HOST_IN_UTMP) || defined(HAVE_HOST_IN_UTMPX)
5260325f 146 strncpy(u.ut_host, host, sizeof(u.ut_host));
4cca272e 147#endif
8efc0c15 148
5260325f 149 /* Figure out the file names. */
150 utmp = _PATH_UTMP;
151 wtmp = _PATH_WTMP;
152
153 login(&u);
a7effaac 154
155#ifdef defined(HAVE_LASTLOG_H) && !defined(DISABLE_LASTLOG)
5260325f 156 lastlog = _PATH_LASTLOG;
157
158 /* Update lastlog unless actually recording a logout. */
159 if (strcmp(user, "") != 0) {
a7effaac 160 int fd;
aa3378df 161 /*
162 * It is safer to bzero the lastlog structure first because
163 * some systems might have some extra fields in it (e.g. SGI)
164 */
5260325f 165 memset(&ll, 0, sizeof(ll));
166
167 /* Update lastlog. */
168 ll.ll_time = time(NULL);
169 strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
170 strncpy(ll.ll_host, host, sizeof(ll.ll_host));
171 fd = open(lastlog, O_RDWR);
172 if (fd >= 0) {
173 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
174 if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
175 log("Could not write %.100s: %.100s", lastlog, strerror(errno));
176 close(fd);
177 }
8efc0c15 178 }
a7effaac 179#endif /* defined(HAVE_LASTLOG_H) && !defined(DISABLE_LASTLOG) */
8efc0c15 180}
5260325f 181
182/* Records that the user has logged out. */
183
184void
185record_logout(int pid, const char *ttyname)
8efc0c15 186{
4cca272e 187#ifdef HAVE_LIBUTIL_LOGIN
5260325f 188 const char *line = ttyname + 5; /* /dev/ttyq8 -> ttyq8 */
189 if (logout(line))
190 logwtmp(line, "", "");
4cca272e 191#else /* HAVE_LIBUTIL_LOGIN */
5260325f 192 record_login(pid, ttyname, "", -1, "", NULL);
4cca272e 193#endif /* HAVE_LIBUTIL_LOGIN */
8efc0c15 194}
This page took 0.101713 seconds and 5 git commands to generate.