summaryrefslogtreecommitdiff
path: root/login.c
diff options
context:
space:
mode:
Diffstat (limited to 'login.c')
-rw-r--r--login.c137
1 files changed, 71 insertions, 66 deletions
diff --git a/login.c b/login.c
index 6749a1556..6fdc71e68 100644
--- a/login.c
+++ b/login.c
@@ -18,7 +18,7 @@
18 */ 18 */
19 19
20#include "includes.h" 20#include "includes.h"
21RCSID("$Id: login.c,v 1.28 2000/05/30 03:12:46 damien Exp $"); 21RCSID("$Id: login.c,v 1.29 2000/05/31 01:20:12 damien Exp $");
22 22
23#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) 23#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
24# include <utmpx.h> 24# include <utmpx.h>
@@ -38,6 +38,11 @@ RCSID("$Id: login.c,v 1.28 2000/05/30 03:12:46 damien Exp $");
38# include <login.h> 38# include <login.h>
39#endif 39#endif
40 40
41#ifdef WITH_AIXAUTHENTICATE
42/* This is done in do_authentication */
43# define DISABLE_LASTLOG
44#endif /* WITH_AIXAUTHENTICATE */
45
41/* 46/*
42 * Returns the time when the user last logged in. Returns 0 if the 47 * 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. 48 * information is not available. This must be called before record_login.
@@ -53,58 +58,50 @@ unsigned long
53get_last_login_time(uid_t uid, const char *logname, 58get_last_login_time(uid_t uid, const char *logname,
54 char *buf, unsigned int bufsize) 59 char *buf, unsigned int bufsize)
55{ 60{
56#if defined(WITH_AIXAUTHENTICATE)
57 /* This is done in do_authentication */
58 return (unsigned long) 0;
59#else
60#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) 61#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
61 struct lastlog ll; 62 struct lastlog ll;
62 char *lastlog;
63 int fd; 63 int fd;
64#ifdef LASTLOG_IS_DIR 64# ifdef LASTLOG_IS_DIR
65 char lbuf[1024]; 65 char lbuf[1024];
66#endif /* LASTLOG_IS_DIR */
67 66
68 lastlog = _PATH_LASTLOG; 67 snprintf(lbuf, sizeof(buf), "%s/%s", _PATH_LASTLOG, logname);
68 if ((fd = open(lbuf, O_RDONLY)) < 0)
69 return 0;
70# else /* LASTLOG_IS_DIR */
69 buf[0] = '\0'; 71 buf[0] = '\0';
70 72
71#ifndef LASTLOG_IS_DIR 73 if ((fd = open(_PATH_LASTLOG, O_RDONLY)) < 0)
72 fd = open(lastlog, O_RDONLY);
73 if (fd < 0)
74 return 0; 74 return 0;
75
75 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); 76 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
76#else /* LASTLOG_IS_DIR */ 77# endif /* LASTLOG_IS_DIR */
77 snprintf(lbuf, sizeof(buf), "%s/%s", lastlog, logname);
78 fd = open(lbuf, O_RDONLY);
79 if (fd < 0)
80 return 0;
81#endif /* LASTLOG_IS_DIR */
82 if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { 78 if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) {
83 close(fd); 79 close(fd);
84 return 0; 80 return 0;
85 } 81 }
82
86 close(fd); 83 close(fd);
84
87 if (bufsize > sizeof(ll.ll_host) + 1) 85 if (bufsize > sizeof(ll.ll_host) + 1)
88 bufsize = sizeof(ll.ll_host) + 1; 86 bufsize = sizeof(ll.ll_host) + 1;
89 strncpy(buf, ll.ll_host, bufsize - 1); 87 strncpy(buf, ll.ll_host, bufsize - 1);
90 buf[bufsize - 1] = 0; 88 buf[bufsize - 1] = 0;
91 return ll.ll_time;
92 89
90 return ll.ll_time;
93#else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ 91#else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
94# ifdef HAVE_TYPE_IN_UTMP 92# ifdef HAVE_TYPE_IN_UTMP
95 /* Look in wtmp for the last login */ 93 /* Look in wtmp for the last login */
96 struct utmp wt; 94 struct utmp wt;
97 char *wt_file = _PATH_WTMP; 95 int fd1;
98 int fd1;
99 unsigned long t = 0; 96 unsigned long t = 0;
100 97
101 if ( (fd1 = open(wt_file, O_RDONLY)) < 0 ) { 98 if ((fd1 = open(_PATH_WTMP, O_RDONLY)) < 0) {
102 error("Couldn't open %.100s to find last login time.", wt_file); 99 error("Couldn't open %.100s to find last login time.", _PATH_WTMP);
103 return 0; 100 return 0;
104 } 101 }
105 102
106 /* seek to last record of file */ 103 /* seek to last record of file */
107 lseek(fd1, (off_t)(0-sizeof(struct utmp)), SEEK_END); 104 lseek(fd1, (off_t)(0 - sizeof(struct utmp)), SEEK_END);
108 105
109 /* loop through wtmp for our last user login record */ 106 /* loop through wtmp for our last user login record */
110 do { 107 do {
@@ -113,47 +110,44 @@ get_last_login_time(uid_t uid, const char *logname,
113 return 0; 110 return 0;
114 } 111 }
115 112
116 if ( wt.ut_type == USER_PROCESS) { 113 if (wt.ut_type == USER_PROCESS) {
117 if ( !strncmp(logname, wt.ut_user, 8) ) { 114 if (!strncmp(logname, wt.ut_user, 8)) {
118 t = (unsigned long) wt.ut_time; 115 t = (unsigned long)wt.ut_time;
119# ifdef HAVE_HOST_IN_UTMP 116# ifdef HAVE_HOST_IN_UTMP
120 if (bufsize > sizeof(wt.ut_host) + 1) 117 if (bufsize > sizeof(wt.ut_host) + 1)
121 bufsize = sizeof(wt.ut_host) + 1; 118 bufsize = sizeof(wt.ut_host) + 1;
122 strncpy(buf, wt.ut_host, bufsize - 1); 119 strncpy(buf, wt.ut_host, bufsize - 1);
123 buf[bufsize - 1] = 0; 120 buf[bufsize - 1] = 0;
124# else /* HAVE_HOST_IN_UTMP */ 121# else /* HAVE_HOST_IN_UTMP */
125 buf[0] = 0; 122 buf[0] = 0;
126# endif /* HAVE_HOST_IN_UTMP */ 123# endif /* HAVE_HOST_IN_UTMP */
127 } 124 }
128 } 125 }
129 126
130 if (lseek(fd1, (off_t)(0-2*sizeof(struct utmp)), SEEK_CUR) == -1) 127 if (lseek(fd1, (off_t)(0 - (2 * sizeof(struct utmp))), SEEK_CUR) < 0)
131 break; 128 break;
132 } while (t == 0); 129 } while (t == 0);
133 130
134 return t; 131 return t;
135# else 132# else /* HAVE_TYPE_IN_UTMP */
136 return 0; 133 return 0;
137# endif /* HAVE_TYPE_IN_UTMP */ 134# endif /* HAVE_TYPE_IN_UTMP */
138#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ 135#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
139#endif /* defined(WITH_AIXAUTHENTICATE) */
140} 136}
141 137
142/* 138/*
143 * Records that the user has logged in. I these parts of operating systems 139 * Records that the user has logged in. I wish these parts of operating
144 * were more standardized. 140 * systems were more standardized.
145 */ 141 */
146
147void 142void
148record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, 143record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
149 const char *host, struct sockaddr * addr) 144 const char *host, struct sockaddr * addr)
150{ 145{
151#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) 146#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
152 struct lastlog ll; 147 struct lastlog ll;
153 char *lastlog; 148# ifdef LASTLOG_IS_DIR
154#ifdef LASTLOG_IS_DIR
155 char buf[1024]; 149 char buf[1024];
156#endif /* LASTLOG_IS_DIR */ 150# endif /* LASTLOG_IS_DIR */
157#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ 151#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
158 struct utmp u; 152 struct utmp u;
159#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) 153#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
@@ -163,28 +157,35 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
163 /* Construct an utmp/wtmp entry. */ 157 /* Construct an utmp/wtmp entry. */
164 memset(&u, 0, sizeof(u)); 158 memset(&u, 0, sizeof(u));
165 strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line)); 159 strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line));
160
166#if defined(HAVE_ID_IN_UTMP) 161#if defined(HAVE_ID_IN_UTMP)
167#ifdef _AIX 162# ifdef _AIX
168 strncpy(u.ut_id, ttyname + 5, sizeof(u.ut_id)); 163 strncpy(u.ut_id, ttyname + 5, sizeof(u.ut_id));
169#else /* !AIX */ 164# else /* !AIX */
170 strncpy(u.ut_id, ttyname + 8, sizeof(u.ut_id)); 165 strncpy(u.ut_id, ttyname + 8, sizeof(u.ut_id));
171#endif 166# endif
172#endif /* defined(HAVE_ID_IN_UTMP) */ 167#endif /* defined(HAVE_ID_IN_UTMP) */
168
173 strncpy(u.ut_name, user, sizeof(u.ut_name)); 169 strncpy(u.ut_name, user, sizeof(u.ut_name));
170
174#if defined(HAVE_TV_IN_UTMP) 171#if defined(HAVE_TV_IN_UTMP)
175 (void)gettimeofday(&u.ut_tv, NULL); 172 (void)gettimeofday(&u.ut_tv, NULL);
176#else /* defined(HAVE_TV_IN_UTMP) */ 173#else /* defined(HAVE_TV_IN_UTMP) */
177 u.ut_time = time(NULL); 174 u.ut_time = time(NULL);
178#endif /* defined(HAVE_TV_IN_UTMP) */ 175#endif /* defined(HAVE_TV_IN_UTMP) */
176
179#if defined(HAVE_PID_IN_UTMP) 177#if defined(HAVE_PID_IN_UTMP)
180 u.ut_pid = (pid_t)pid; 178 u.ut_pid = (pid_t)pid;
181#endif /* HAVE_PID_IN_UTMP */ 179#endif /* HAVE_PID_IN_UTMP */
180
182#if defined(HAVE_TYPE_IN_UTMP) 181#if defined(HAVE_TYPE_IN_UTMP)
183 u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; 182 u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS;
184#endif /* HAVE_TYPE_IN_UTMP */ 183#endif /* HAVE_TYPE_IN_UTMP */
184
185#if defined(HAVE_HOST_IN_UTMP) 185#if defined(HAVE_HOST_IN_UTMP)
186 strncpy(u.ut_host, host, sizeof(u.ut_host)); 186 strncpy(u.ut_host, host, sizeof(u.ut_host));
187#endif 187#endif
188
188#if defined(HAVE_ADDR_IN_UTMP) 189#if defined(HAVE_ADDR_IN_UTMP)
189 if (addr) { 190 if (addr) {
190 switch (addr->sa_family) { 191 switch (addr->sa_family) {
@@ -193,26 +194,29 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
193 memcpy(&(u.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); 194 memcpy(&(u.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr)));
194 break; 195 break;
195 } 196 }
196#if defined(HAVE_ADDR_V6_IN_UTMP) 197# if defined(HAVE_ADDR_V6_IN_UTMP)
197 case AF_INET6: { 198 case AF_INET6: {
198 struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; 199 struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
199 memcpy(u.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); 200 memcpy(u.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr)));
200 break; 201 break;
201 } 202 }
202#endif 203# endif /* defined(HAVE_ADDR_V6_IN_UTMP) */
203 default: 204 default:
204 break; 205 break;
205 } 206 }
206 } 207 }
207#endif 208#endif /* defined(HAVE_ADDR_IN_UTMP) */
208 209
209#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) 210#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
210 memset(&utx, 0, sizeof(utx)); 211 memset(&utx, 0, sizeof(utx));
212
211 strncpy(utx.ut_user, user, sizeof(utx.ut_name)); 213 strncpy(utx.ut_user, user, sizeof(utx.ut_name));
212 strncpy(utx.ut_line, ttyname + 5, sizeof(utx.ut_line)); 214 strncpy(utx.ut_line, ttyname + 5, sizeof(utx.ut_line));
213 strncpy(utx.ut_id, ttyname + 8, sizeof(utx.ut_id)); 215 strncpy(utx.ut_id, ttyname + 8, sizeof(utx.ut_id));
216
214 utx.ut_pid = (pid_t)pid; 217 utx.ut_pid = (pid_t)pid;
215 (void)gettimeofday(&utx.ut_tv, NULL); 218 (void)gettimeofday(&utx.ut_tv, NULL);
219
216 utx.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; 220 utx.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS;
217# ifdef HAVE_HOST_IN_UTMPX 221# ifdef HAVE_HOST_IN_UTMPX
218# ifdef HAVE_SYSLEN_IN_UTMPX 222# ifdef HAVE_SYSLEN_IN_UTMPX
@@ -225,7 +229,8 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
225# endif /* HAVE_SYSLEN_IN_UTMPX */ 229# endif /* HAVE_SYSLEN_IN_UTMPX */
226 utx.ut_host[sizeof(utx.ut_host)-1] = '\0'; 230 utx.ut_host[sizeof(utx.ut_host)-1] = '\0';
227# endif 231# endif
228#if defined(HAVE_ADDR_IN_UTMPX) 232
233# if defined(HAVE_ADDR_IN_UTMPX)
229 if (addr) { 234 if (addr) {
230 switch (addr->sa_family) { 235 switch (addr->sa_family) {
231 case AF_INET: { 236 case AF_INET: {
@@ -233,31 +238,27 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
233 memcpy(&(utx.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); 238 memcpy(&(utx.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr)));
234 break; 239 break;
235 } 240 }
236#if defined(HAVE_ADDR_V6_IN_UTMPX) 241# if defined(HAVE_ADDR_V6_IN_UTMPX)
237 case AF_INET6: { 242 case AF_INET6: {
238 struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; 243 struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr;
239 memcpy(utx.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); 244 memcpy(utx.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr)));
240 break; 245 break;
241 } 246 }
242#endif 247# endif /* defined(HAVE_ADDR_V6_IN_UTMPX) */
243 default: 248 default:
244 break; 249 break;
245 } 250 }
246 } 251 }
247#endif 252# endif /* defined(HAVE_ADDR_IN_UTMPX) */
248#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ 253#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
249 254
250/*#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) && !defined(HAVE_LOGIN)*/
251#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) 255#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX)
252 login(&u, &utx); 256 login(&u, &utx);
253#else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ 257#else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
254 login(&u); 258 login(&u);
255#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ 259#endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
256 260
257#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) && !defined(WITH_AIXAUTHENTICATE) 261#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
258 /* AIX does this in do_authentication */
259 lastlog = _PATH_LASTLOG;
260
261 /* Update lastlog unless actually recording a logout. */ 262 /* Update lastlog unless actually recording a logout. */
262 if (strcmp(user, "") != 0) { 263 if (strcmp(user, "") != 0) {
263 int fd; 264 int fd;
@@ -271,21 +272,25 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
271 ll.ll_time = time(NULL); 272 ll.ll_time = time(NULL);
272 strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line)); 273 strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line));
273 strncpy(ll.ll_host, host, sizeof(ll.ll_host)); 274 strncpy(ll.ll_host, host, sizeof(ll.ll_host));
274#ifdef LASTLOG_IS_DIR 275# ifdef LASTLOG_IS_DIR
275 snprintf(buf, sizeof(buf), "%s/%s", lastlog, user); 276 snprintf(buf, sizeof(buf), "%s/%s", _PATH_LASTLOG, user);
276 fd = open(buf, O_RDWR); 277 if ((fd = open(buf, O_RDWR)) >= 0) {
277 if (fd >= 0) {
278#else /* LASTLOG_IS_DIR */
279 fd = open(lastlog, O_RDWR);
280 if (fd >= 0) {
281 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
282#endif /* LASTLOG_IS_DIR */
283 if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) 278 if (write(fd, &ll, sizeof(ll)) != sizeof(ll))
284 log("Could not write %.100s: %.100s", lastlog, strerror(errno)); 279 log("Could not write %.100s: %.100s", buf, strerror(errno));
285 close(fd); 280 close(fd);
286 } 281 }
282# else /* LASTLOG_IS_DIR */
283 if ((fd = open(_PATH_LASTLOG, O_RDWR)) >= 0) {
284 lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET);
285 if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) {
286 log("Could not write %.100s: %.100s", _PATH_LASTLOG,
287 strerror(errno));
288 }
289 close(fd);
290 }
291# endif /* LASTLOG_IS_DIR */
287 } 292 }
288#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) && !defined(WITH_AIXAUTHENTICATE) */ 293#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
289} 294}
290 295
291/* Records that the user has logged out. */ 296/* Records that the user has logged out. */