diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | loginrec.c | 642 |
2 files changed, 321 insertions, 327 deletions
@@ -1,3 +1,7 @@ | |||
1 | 20040912 | ||
2 | - (djm) [loginrec.c] Start KNF and tidy up of this long-neglected file. | ||
3 | No change in resultant binary | ||
4 | |||
1 | 20040911 | 5 | 20040911 |
2 | - (djm) [ssh-agent.c] unifdef some cygwin code; ok dtucker@ | 6 | - (djm) [ssh-agent.c] unifdef some cygwin code; ok dtucker@ |
3 | - (dtucker) [auth-pam.c auth-pam.h session.c] Bug #890: Send output from | 7 | - (dtucker) [auth-pam.c auth-pam.h session.c] Bug #890: Send output from |
@@ -1734,4 +1738,4 @@ | |||
1734 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM | 1738 | - (djm) Trim deprecated options from INSTALL. Mention UsePAM |
1735 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu | 1739 | - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu |
1736 | 1740 | ||
1737 | $Id: ChangeLog,v 1.3547 2004/09/11 13:32:09 dtucker Exp $ | 1741 | $Id: ChangeLog,v 1.3548 2004/09/12 05:23:14 djm Exp $ |
diff --git a/loginrec.c b/loginrec.c index 3ec378b9a..8d48fb99f 100644 --- a/loginrec.c +++ b/loginrec.c | |||
@@ -30,125 +30,99 @@ | |||
30 | **/ | 30 | **/ |
31 | 31 | ||
32 | /* | 32 | /* |
33 | The new login code explained | 33 | * The new login code explained |
34 | ============================ | 34 | * ============================ |
35 | 35 | * | |
36 | This code attempts to provide a common interface to login recording | 36 | * This code attempts to provide a common interface to login recording |
37 | (utmp and friends) and last login time retrieval. | 37 | * (utmp and friends) and last login time retrieval. |
38 | 38 | * | |
39 | Its primary means of achieving this is to use 'struct logininfo', a | 39 | * Its primary means of achieving this is to use 'struct logininfo', a |
40 | union of all the useful fields in the various different types of | 40 | * union of all the useful fields in the various different types of |
41 | system login record structures one finds on UNIX variants. | 41 | * system login record structures one finds on UNIX variants. |
42 | 42 | * | |
43 | We depend on autoconf to define which recording methods are to be | 43 | * We depend on autoconf to define which recording methods are to be |
44 | used, and which fields are contained in the relevant data structures | 44 | * used, and which fields are contained in the relevant data structures |
45 | on the local system. Many C preprocessor symbols affect which code | 45 | * on the local system. Many C preprocessor symbols affect which code |
46 | gets compiled here. | 46 | * gets compiled here. |
47 | 47 | * | |
48 | The code is designed to make it easy to modify a particular | 48 | * The code is designed to make it easy to modify a particular |
49 | recording method, without affecting other methods nor requiring so | 49 | * recording method, without affecting other methods nor requiring so |
50 | many nested conditional compilation blocks as were commonplace in | 50 | * many nested conditional compilation blocks as were commonplace in |
51 | the old code. | 51 | * the old code. |
52 | 52 | * | |
53 | For login recording, we try to use the local system's libraries as | 53 | * For login recording, we try to use the local system's libraries as |
54 | these are clearly most likely to work correctly. For utmp systems | 54 | * these are clearly most likely to work correctly. For utmp systems |
55 | this usually means login() and logout() or setutent() etc., probably | 55 | * this usually means login() and logout() or setutent() etc., probably |
56 | in libutil, along with logwtmp() etc. On these systems, we fall back | 56 | * in libutil, along with logwtmp() etc. On these systems, we fall back |
57 | to writing the files directly if we have to, though this method | 57 | * to writing the files directly if we have to, though this method |
58 | requires very thorough testing so we do not corrupt local auditing | 58 | * requires very thorough testing so we do not corrupt local auditing |
59 | information. These files and their access methods are very system | 59 | * information. These files and their access methods are very system |
60 | specific indeed. | 60 | * specific indeed. |
61 | 61 | * | |
62 | For utmpx systems, the corresponding library functions are | 62 | * For utmpx systems, the corresponding library functions are |
63 | setutxent() etc. To the author's knowledge, all utmpx systems have | 63 | * setutxent() etc. To the author's knowledge, all utmpx systems have |
64 | these library functions and so no direct write is attempted. If such | 64 | * these library functions and so no direct write is attempted. If such |
65 | a system exists and needs support, direct analogues of the [uw]tmp | 65 | * a system exists and needs support, direct analogues of the [uw]tmp |
66 | code should suffice. | 66 | * code should suffice. |
67 | 67 | * | |
68 | Retrieving the time of last login ('lastlog') is in some ways even | 68 | * Retrieving the time of last login ('lastlog') is in some ways even |
69 | more problemmatic than login recording. Some systems provide a | 69 | * more problemmatic than login recording. Some systems provide a |
70 | simple table of all users which we seek based on uid and retrieve a | 70 | * simple table of all users which we seek based on uid and retrieve a |
71 | relatively standard structure. Others record the same information in | 71 | * relatively standard structure. Others record the same information in |
72 | a directory with a separate file, and others don't record the | 72 | * a directory with a separate file, and others don't record the |
73 | information separately at all. For systems in the latter category, | 73 | * information separately at all. For systems in the latter category, |
74 | we look backwards in the wtmp or wtmpx file for the last login entry | 74 | * we look backwards in the wtmp or wtmpx file for the last login entry |
75 | for our user. Naturally this is slower and on busy systems could | 75 | * for our user. Naturally this is slower and on busy systems could |
76 | incur a significant performance penalty. | 76 | * incur a significant performance penalty. |
77 | 77 | * | |
78 | Calling the new code | 78 | * Calling the new code |
79 | -------------------- | 79 | * -------------------- |
80 | 80 | * | |
81 | In OpenSSH all login recording and retrieval is performed in | 81 | * In OpenSSH all login recording and retrieval is performed in |
82 | login.c. Here you'll find working examples. Also, in the logintest.c | 82 | * login.c. Here you'll find working examples. Also, in the logintest.c |
83 | program there are more examples. | 83 | * program there are more examples. |
84 | 84 | * | |
85 | Internal handler calling method | 85 | * Internal handler calling method |
86 | ------------------------------- | 86 | * ------------------------------- |
87 | 87 | * | |
88 | When a call is made to login_login() or login_logout(), both | 88 | * When a call is made to login_login() or login_logout(), both |
89 | routines set a struct logininfo flag defining which action (log in, | 89 | * routines set a struct logininfo flag defining which action (log in, |
90 | or log out) is to be taken. They both then call login_write(), which | 90 | * or log out) is to be taken. They both then call login_write(), which |
91 | calls whichever of the many structure-specific handlers autoconf | 91 | * calls whichever of the many structure-specific handlers autoconf |
92 | selects for the local system. | 92 | * selects for the local system. |
93 | 93 | * | |
94 | The handlers themselves handle system data structure specifics. Both | 94 | * The handlers themselves handle system data structure specifics. Both |
95 | struct utmp and struct utmpx have utility functions (see | 95 | * struct utmp and struct utmpx have utility functions (see |
96 | construct_utmp*()) to try to make it simpler to add extra systems | 96 | * construct_utmp*()) to try to make it simpler to add extra systems |
97 | that introduce new features to either structure. | 97 | * that introduce new features to either structure. |
98 | 98 | * | |
99 | While it may seem terribly wasteful to replicate so much similar | 99 | * While it may seem terribly wasteful to replicate so much similar |
100 | code for each method, experience has shown that maintaining code to | 100 | * code for each method, experience has shown that maintaining code to |
101 | write both struct utmp and utmpx in one function, whilst maintaining | 101 | * write both struct utmp and utmpx in one function, whilst maintaining |
102 | support for all systems whether they have library support or not, is | 102 | * support for all systems whether they have library support or not, is |
103 | a difficult and time-consuming task. | 103 | * a difficult and time-consuming task. |
104 | 104 | * | |
105 | Lastlog support proceeds similarly. Functions login_get_lastlog() | 105 | * Lastlog support proceeds similarly. Functions login_get_lastlog() |
106 | (and its OpenSSH-tuned friend login_get_lastlog_time()) call | 106 | * (and its OpenSSH-tuned friend login_get_lastlog_time()) call |
107 | getlast_entry(), which tries one of three methods to find the last | 107 | * getlast_entry(), which tries one of three methods to find the last |
108 | login time. It uses local system lastlog support if it can, | 108 | * login time. It uses local system lastlog support if it can, |
109 | otherwise it tries wtmp or wtmpx before giving up and returning 0, | 109 | * otherwise it tries wtmp or wtmpx before giving up and returning 0, |
110 | meaning "tilt". | 110 | * meaning "tilt". |
111 | 111 | * | |
112 | Maintenance | 112 | * Maintenance |
113 | ----------- | 113 | * ----------- |
114 | 114 | * | |
115 | In many cases it's possible to tweak autoconf to select the correct | 115 | * In many cases it's possible to tweak autoconf to select the correct |
116 | methods for a particular platform, either by improving the detection | 116 | * methods for a particular platform, either by improving the detection |
117 | code (best), or by presetting DISABLE_<method> or CONF_<method>_FILE | 117 | * code (best), or by presetting DISABLE_<method> or CONF_<method>_FILE |
118 | symbols for the platform. | 118 | * symbols for the platform. |
119 | 119 | * | |
120 | Use logintest to check which symbols are defined before modifying | 120 | * Use logintest to check which symbols are defined before modifying |
121 | configure.ac and loginrec.c. (You have to build logintest yourself | 121 | * configure.ac and loginrec.c. (You have to build logintest yourself |
122 | with 'make logintest' as it's not built by default.) | 122 | * with 'make logintest' as it's not built by default.) |
123 | 123 | * | |
124 | Otherwise, patches to the specific method(s) are very helpful! | 124 | * Otherwise, patches to the specific method(s) are very helpful! |
125 | 125 | */ | |
126 | */ | ||
127 | |||
128 | /** | ||
129 | ** TODO: | ||
130 | ** homegrown ttyslot() | ||
131 | ** test, test, test | ||
132 | ** | ||
133 | ** Platform status: | ||
134 | ** ---------------- | ||
135 | ** | ||
136 | ** Known good: | ||
137 | ** Linux (Redhat 6.2, Debian) | ||
138 | ** Solaris | ||
139 | ** HP-UX 10.20 (gcc only) | ||
140 | ** IRIX | ||
141 | ** NeXT - M68k/HPPA/Sparc (4.2/3.3) | ||
142 | ** | ||
143 | ** Testing required: Please send reports! | ||
144 | ** NetBSD | ||
145 | ** HP-UX 11 | ||
146 | ** AIX | ||
147 | ** | ||
148 | ** Platforms with known problems: | ||
149 | ** Some variants of Slackware Linux | ||
150 | ** | ||
151 | **/ | ||
152 | 126 | ||
153 | #include "includes.h" | 127 | #include "includes.h" |
154 | 128 | ||
@@ -158,16 +132,16 @@ | |||
158 | #include "log.h" | 132 | #include "log.h" |
159 | #include "atomicio.h" | 133 | #include "atomicio.h" |
160 | 134 | ||
161 | RCSID("$Id: loginrec.c,v 1.59 2004/08/23 11:53:28 djm Exp $"); | ||
162 | |||
163 | #ifdef HAVE_UTIL_H | 135 | #ifdef HAVE_UTIL_H |
164 | # include <util.h> | 136 | # include <util.h> |
165 | #endif | 137 | #endif |
166 | 138 | ||
167 | #ifdef HAVE_LIBUTIL_H | 139 | #ifdef HAVE_LIBUTIL_H |
168 | # include <libutil.h> | 140 | # include <libutil.h> |
169 | #endif | 141 | #endif |
170 | 142 | ||
143 | RCSID("$Id: loginrec.c,v 1.60 2004/09/12 05:18:55 djm Exp $"); | ||
144 | |||
171 | /** | 145 | /** |
172 | ** prototypes for helper functions in this file | 146 | ** prototypes for helper functions in this file |
173 | **/ | 147 | **/ |
@@ -195,13 +169,14 @@ int wtmp_get_entry(struct logininfo *li); | |||
195 | int wtmpx_get_entry(struct logininfo *li); | 169 | int wtmpx_get_entry(struct logininfo *li); |
196 | 170 | ||
197 | /* pick the shortest string */ | 171 | /* pick the shortest string */ |
198 | #define MIN_SIZEOF(s1,s2) ( sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2) ) | 172 | #define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2)) |
199 | 173 | ||
200 | /** | 174 | /** |
201 | ** platform-independent login functions | 175 | ** platform-independent login functions |
202 | **/ | 176 | **/ |
203 | 177 | ||
204 | /* login_login(struct logininfo *) -Record a login | 178 | /* |
179 | * login_login(struct logininfo *) - Record a login | ||
205 | * | 180 | * |
206 | * Call with a pointer to a struct logininfo initialised with | 181 | * Call with a pointer to a struct logininfo initialised with |
207 | * login_init_entry() or login_alloc_entry() | 182 | * login_init_entry() or login_alloc_entry() |
@@ -211,14 +186,15 @@ int wtmpx_get_entry(struct logininfo *li); | |||
211 | * 0 on failure (will use OpenSSH's logging facilities for diagnostics) | 186 | * 0 on failure (will use OpenSSH's logging facilities for diagnostics) |
212 | */ | 187 | */ |
213 | int | 188 | int |
214 | login_login (struct logininfo *li) | 189 | login_login(struct logininfo *li) |
215 | { | 190 | { |
216 | li->type = LTYPE_LOGIN; | 191 | li->type = LTYPE_LOGIN; |
217 | return login_write(li); | 192 | return (login_write(li)); |
218 | } | 193 | } |
219 | 194 | ||
220 | 195 | ||
221 | /* login_logout(struct logininfo *) - Record a logout | 196 | /* |
197 | * login_logout(struct logininfo *) - Record a logout | ||
222 | * | 198 | * |
223 | * Call as with login_login() | 199 | * Call as with login_login() |
224 | * | 200 | * |
@@ -230,10 +206,11 @@ int | |||
230 | login_logout(struct logininfo *li) | 206 | login_logout(struct logininfo *li) |
231 | { | 207 | { |
232 | li->type = LTYPE_LOGOUT; | 208 | li->type = LTYPE_LOGOUT; |
233 | return login_write(li); | 209 | return (login_write(li)); |
234 | } | 210 | } |
235 | 211 | ||
236 | /* login_get_lastlog_time(int) - Retrieve the last login time | 212 | /* |
213 | * login_get_lastlog_time(int) - Retrieve the last login time | ||
237 | * | 214 | * |
238 | * Retrieve the last login time for the given uid. Will try to use the | 215 | * Retrieve the last login time for the given uid. Will try to use the |
239 | * system lastlog facilities if they are available, but will fall back | 216 | * system lastlog facilities if they are available, but will fall back |
@@ -256,12 +233,13 @@ login_get_lastlog_time(const int uid) | |||
256 | struct logininfo li; | 233 | struct logininfo li; |
257 | 234 | ||
258 | if (login_get_lastlog(&li, uid)) | 235 | if (login_get_lastlog(&li, uid)) |
259 | return li.tv_sec; | 236 | return (li.tv_sec); |
260 | else | 237 | else |
261 | return 0; | 238 | return (0); |
262 | } | 239 | } |
263 | 240 | ||
264 | /* login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry | 241 | /* |
242 | * login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry | ||
265 | * | 243 | * |
266 | * Retrieve a logininfo structure populated (only partially) with | 244 | * Retrieve a logininfo structure populated (only partially) with |
267 | * information from the system lastlog data, or from wtmp/wtmpx if no | 245 | * information from the system lastlog data, or from wtmp/wtmpx if no |
@@ -272,7 +250,6 @@ login_get_lastlog_time(const int uid) | |||
272 | * Returns: | 250 | * Returns: |
273 | * >0: A pointer to your struct logininfo if successful | 251 | * >0: A pointer to your struct logininfo if successful |
274 | * 0 on failure (will use OpenSSH's logging facilities for diagnostics) | 252 | * 0 on failure (will use OpenSSH's logging facilities for diagnostics) |
275 | * | ||
276 | */ | 253 | */ |
277 | struct logininfo * | 254 | struct logininfo * |
278 | login_get_lastlog(struct logininfo *li, const int uid) | 255 | login_get_lastlog(struct logininfo *li, const int uid) |
@@ -292,17 +269,18 @@ login_get_lastlog(struct logininfo *li, const int uid) | |||
292 | fatal("login_get_lastlog: Cannot find account for uid %i", uid); | 269 | fatal("login_get_lastlog: Cannot find account for uid %i", uid); |
293 | 270 | ||
294 | /* No MIN_SIZEOF here - we absolutely *must not* truncate the | 271 | /* No MIN_SIZEOF here - we absolutely *must not* truncate the |
295 | * username */ | 272 | * username (XXX - so check for trunc!) */ |
296 | strlcpy(li->username, pw->pw_name, sizeof(li->username)); | 273 | strlcpy(li->username, pw->pw_name, sizeof(li->username)); |
297 | 274 | ||
298 | if (getlast_entry(li)) | 275 | if (getlast_entry(li)) |
299 | return li; | 276 | return (li); |
300 | else | 277 | else |
301 | return NULL; | 278 | return (NULL); |
302 | } | 279 | } |
303 | 280 | ||
304 | 281 | ||
305 | /* login_alloc_entry(int, char*, char*, char*) - Allocate and initialise | 282 | /* |
283 | * login_alloc_entry(int, char*, char*, char*) - Allocate and initialise | ||
306 | * a logininfo structure | 284 | * a logininfo structure |
307 | * | 285 | * |
308 | * This function creates a new struct logininfo, a data structure | 286 | * This function creates a new struct logininfo, a data structure |
@@ -313,13 +291,13 @@ login_get_lastlog(struct logininfo *li, const int uid) | |||
313 | */ | 291 | */ |
314 | struct | 292 | struct |
315 | logininfo *login_alloc_entry(int pid, const char *username, | 293 | logininfo *login_alloc_entry(int pid, const char *username, |
316 | const char *hostname, const char *line) | 294 | const char *hostname, const char *line) |
317 | { | 295 | { |
318 | struct logininfo *newli; | 296 | struct logininfo *newli; |
319 | 297 | ||
320 | newli = (struct logininfo *) xmalloc (sizeof(*newli)); | 298 | newli = xmalloc(sizeof(*newli)); |
321 | (void)login_init_entry(newli, pid, username, hostname, line); | 299 | login_init_entry(newli, pid, username, hostname, line); |
322 | return newli; | 300 | return (newli); |
323 | } | 301 | } |
324 | 302 | ||
325 | 303 | ||
@@ -341,7 +319,7 @@ login_free_entry(struct logininfo *li) | |||
341 | */ | 319 | */ |
342 | int | 320 | int |
343 | login_init_entry(struct logininfo *li, int pid, const char *username, | 321 | login_init_entry(struct logininfo *li, int pid, const char *username, |
344 | const char *hostname, const char *line) | 322 | const char *hostname, const char *line) |
345 | { | 323 | { |
346 | struct passwd *pw; | 324 | struct passwd *pw; |
347 | 325 | ||
@@ -356,18 +334,21 @@ login_init_entry(struct logininfo *li, int pid, const char *username, | |||
356 | if (username) { | 334 | if (username) { |
357 | strlcpy(li->username, username, sizeof(li->username)); | 335 | strlcpy(li->username, username, sizeof(li->username)); |
358 | pw = getpwnam(li->username); | 336 | pw = getpwnam(li->username); |
359 | if (pw == NULL) | 337 | if (pw == NULL) { |
360 | fatal("login_init_entry: Cannot find user \"%s\"", li->username); | 338 | fatal("login_init_entry: Cannot find user \"%s\"", |
339 | li->username); | ||
340 | } | ||
361 | li->uid = pw->pw_uid; | 341 | li->uid = pw->pw_uid; |
362 | } | 342 | } |
363 | 343 | ||
364 | if (hostname) | 344 | if (hostname) |
365 | strlcpy(li->hostname, hostname, sizeof(li->hostname)); | 345 | strlcpy(li->hostname, hostname, sizeof(li->hostname)); |
366 | 346 | ||
367 | return 1; | 347 | return (1); |
368 | } | 348 | } |
369 | 349 | ||
370 | /* login_set_current_time(struct logininfo *) - set the current time | 350 | /* |
351 | * login_set_current_time(struct logininfo *) - set the current time | ||
371 | * | 352 | * |
372 | * Set the current time in a logininfo structure. This function is | 353 | * Set the current time in a logininfo structure. This function is |
373 | * meant to eliminate the need to deal with system dependencies for | 354 | * meant to eliminate the need to deal with system dependencies for |
@@ -387,7 +368,7 @@ login_set_current_time(struct logininfo *li) | |||
387 | /* copy a sockaddr_* into our logininfo */ | 368 | /* copy a sockaddr_* into our logininfo */ |
388 | void | 369 | void |
389 | login_set_addr(struct logininfo *li, const struct sockaddr *sa, | 370 | login_set_addr(struct logininfo *li, const struct sockaddr *sa, |
390 | const unsigned int sa_size) | 371 | const unsigned int sa_size) |
391 | { | 372 | { |
392 | unsigned int bufsize = sa_size; | 373 | unsigned int bufsize = sa_size; |
393 | 374 | ||
@@ -395,7 +376,7 @@ login_set_addr(struct logininfo *li, const struct sockaddr *sa, | |||
395 | if (sizeof(li->hostaddr) < sa_size) | 376 | if (sizeof(li->hostaddr) < sa_size) |
396 | bufsize = sizeof(li->hostaddr); | 377 | bufsize = sizeof(li->hostaddr); |
397 | 378 | ||
398 | memcpy((void *)&(li->hostaddr.sa), (const void *)sa, bufsize); | 379 | memcpy(&li->hostaddr.sa, sa, bufsize); |
399 | } | 380 | } |
400 | 381 | ||
401 | 382 | ||
@@ -404,12 +385,12 @@ login_set_addr(struct logininfo *li, const struct sockaddr *sa, | |||
404 | ** results | 385 | ** results |
405 | **/ | 386 | **/ |
406 | int | 387 | int |
407 | login_write (struct logininfo *li) | 388 | login_write(struct logininfo *li) |
408 | { | 389 | { |
409 | #ifndef HAVE_CYGWIN | 390 | #ifndef HAVE_CYGWIN |
410 | if ((int)geteuid() != 0) { | 391 | if (geteuid() != 0) { |
411 | logit("Attempt to write login records by non-root user (aborting)"); | 392 | logit("Attempt to write login records by non-root user (aborting)"); |
412 | return 1; | 393 | return (1); |
413 | } | 394 | } |
414 | #endif | 395 | #endif |
415 | 396 | ||
@@ -419,9 +400,8 @@ login_write (struct logininfo *li) | |||
419 | syslogin_write_entry(li); | 400 | syslogin_write_entry(li); |
420 | #endif | 401 | #endif |
421 | #ifdef USE_LASTLOG | 402 | #ifdef USE_LASTLOG |
422 | if (li->type == LTYPE_LOGIN) { | 403 | if (li->type == LTYPE_LOGIN) |
423 | lastlog_write_entry(li); | 404 | lastlog_write_entry(li); |
424 | } | ||
425 | #endif | 405 | #endif |
426 | #ifdef USE_UTMP | 406 | #ifdef USE_UTMP |
427 | utmp_write_entry(li); | 407 | utmp_write_entry(li); |
@@ -440,7 +420,7 @@ login_write (struct logininfo *li) | |||
440 | !sys_auth_record_login(li->username,li->hostname,li->line)) | 420 | !sys_auth_record_login(li->username,li->hostname,li->line)) |
441 | logit("Writing login record failed for %s", li->username); | 421 | logit("Writing login record failed for %s", li->username); |
442 | #endif | 422 | #endif |
443 | return 0; | 423 | return (0); |
444 | } | 424 | } |
445 | 425 | ||
446 | #ifdef LOGIN_NEEDS_UTMPX | 426 | #ifdef LOGIN_NEEDS_UTMPX |
@@ -461,7 +441,7 @@ login_utmp_only(struct logininfo *li) | |||
461 | # ifdef USE_WTMPX | 441 | # ifdef USE_WTMPX |
462 | wtmpx_write_entry(li); | 442 | wtmpx_write_entry(li); |
463 | # endif | 443 | # endif |
464 | return 0; | 444 | return (0); |
465 | } | 445 | } |
466 | #endif | 446 | #endif |
467 | 447 | ||
@@ -478,25 +458,21 @@ getlast_entry(struct logininfo *li) | |||
478 | return(lastlog_get_entry(li)); | 458 | return(lastlog_get_entry(li)); |
479 | #else /* !USE_LASTLOG */ | 459 | #else /* !USE_LASTLOG */ |
480 | 460 | ||
481 | #ifdef DISABLE_LASTLOG | 461 | #if defined(DISABLE_LASTLOG) |
482 | /* On some systems we shouldn't even try to obtain last login | 462 | /* On some systems we shouldn't even try to obtain last login |
483 | * time, e.g. AIX */ | 463 | * time, e.g. AIX */ |
484 | return 0; | 464 | return (0); |
485 | # else /* DISABLE_LASTLOG */ | 465 | # elif defined(USE_WTMP) && \ |
486 | /* Try to retrieve the last login time from wtmp */ | 466 | (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) |
487 | # if defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) | ||
488 | /* retrieve last login time from utmp */ | 467 | /* retrieve last login time from utmp */ |
489 | return (wtmp_get_entry(li)); | 468 | return (wtmp_get_entry(li)); |
490 | # else /* defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) */ | 469 | # elif defined(USE_WTMPX) && \ |
470 | (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) | ||
491 | /* If wtmp isn't available, try wtmpx */ | 471 | /* If wtmp isn't available, try wtmpx */ |
492 | # if defined(USE_WTMPX) && (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX)) | ||
493 | /* retrieve last login time from utmpx */ | ||
494 | return (wtmpx_get_entry(li)); | 472 | return (wtmpx_get_entry(li)); |
495 | # else | 473 | # else |
496 | /* Give up: No means of retrieving last login time */ | 474 | /* Give up: No means of retrieving last login time */ |
497 | return 0; | 475 | return (0); |
498 | # endif /* USE_WTMPX && (HAVE_TIME_IN_UTMPX || HAVE_TV_IN_UTMPX) */ | ||
499 | # endif /* USE_WTMP && (HAVE_TIME_IN_UTMP || HAVE_TV_IN_UTMP) */ | ||
500 | # endif /* DISABLE_LASTLOG */ | 476 | # endif /* DISABLE_LASTLOG */ |
501 | #endif /* USE_LASTLOG */ | 477 | #endif /* USE_LASTLOG */ |
502 | } | 478 | } |
@@ -520,19 +496,21 @@ getlast_entry(struct logininfo *li) | |||
520 | */ | 496 | */ |
521 | 497 | ||
522 | 498 | ||
523 | /* line_fullname(): add the leading '/dev/' if it doesn't exist make | 499 | /* |
524 | * sure dst has enough space, if not just copy src (ugh) */ | 500 | * line_fullname(): add the leading '/dev/' if it doesn't exist make |
501 | * sure dst has enough space, if not just copy src (ugh) | ||
502 | */ | ||
525 | char * | 503 | char * |
526 | line_fullname(char *dst, const char *src, int dstsize) | 504 | line_fullname(char *dst, const char *src, int dstsize) |
527 | { | 505 | { |
528 | memset(dst, '\0', dstsize); | 506 | memset(dst, '\0', dstsize); |
529 | if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) { | 507 | if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) |
530 | strlcpy(dst, src, dstsize); | 508 | strlcpy(dst, src, dstsize); |
531 | } else { | 509 | else { |
532 | strlcpy(dst, "/dev/", dstsize); | 510 | strlcpy(dst, "/dev/", dstsize); |
533 | strlcat(dst, src, dstsize); | 511 | strlcat(dst, src, dstsize); |
534 | } | 512 | } |
535 | return dst; | 513 | return (dst); |
536 | } | 514 | } |
537 | 515 | ||
538 | /* line_stripname(): strip the leading '/dev' if it exists, return dst */ | 516 | /* line_stripname(): strip the leading '/dev' if it exists, return dst */ |
@@ -544,15 +522,17 @@ line_stripname(char *dst, const char *src, int dstsize) | |||
544 | strlcpy(dst, src + 5, dstsize); | 522 | strlcpy(dst, src + 5, dstsize); |
545 | else | 523 | else |
546 | strlcpy(dst, src, dstsize); | 524 | strlcpy(dst, src, dstsize); |
547 | return dst; | 525 | return (dst); |
548 | } | 526 | } |
549 | 527 | ||
550 | /* line_abbrevname(): Return the abbreviated (usually four-character) | 528 | /* |
529 | * line_abbrevname(): Return the abbreviated (usually four-character) | ||
551 | * form of the line (Just use the last <dstsize> characters of the | 530 | * form of the line (Just use the last <dstsize> characters of the |
552 | * full name.) | 531 | * full name.) |
553 | * | 532 | * |
554 | * NOTE: use strncpy because we do NOT necessarily want zero | 533 | * NOTE: use strncpy because we do NOT necessarily want zero |
555 | * termination */ | 534 | * termination |
535 | */ | ||
556 | char * | 536 | char * |
557 | line_abbrevname(char *dst, const char *src, int dstsize) | 537 | line_abbrevname(char *dst, const char *src, int dstsize) |
558 | { | 538 | { |
@@ -579,7 +559,7 @@ line_abbrevname(char *dst, const char *src, int dstsize) | |||
579 | strncpy(dst, src, (size_t)dstsize); | 559 | strncpy(dst, src, (size_t)dstsize); |
580 | } | 560 | } |
581 | 561 | ||
582 | return dst; | 562 | return (dst); |
583 | } | 563 | } |
584 | 564 | ||
585 | /** | 565 | /** |
@@ -595,13 +575,11 @@ line_abbrevname(char *dst, const char *src, int dstsize) | |||
595 | void | 575 | void |
596 | set_utmp_time(struct logininfo *li, struct utmp *ut) | 576 | set_utmp_time(struct logininfo *li, struct utmp *ut) |
597 | { | 577 | { |
598 | # ifdef HAVE_TV_IN_UTMP | 578 | # if defined(HAVE_TV_IN_UTMP) |
599 | ut->ut_tv.tv_sec = li->tv_sec; | 579 | ut->ut_tv.tv_sec = li->tv_sec; |
600 | ut->ut_tv.tv_usec = li->tv_usec; | 580 | ut->ut_tv.tv_usec = li->tv_usec; |
601 | # else | 581 | # elif defined(HAVE_TIME_IN_UTMP) |
602 | # ifdef HAVE_TIME_IN_UTMP | ||
603 | ut->ut_time = li->tv_sec; | 582 | ut->ut_time = li->tv_sec; |
604 | # endif | ||
605 | # endif | 583 | # endif |
606 | } | 584 | } |
607 | 585 | ||
@@ -611,7 +589,8 @@ construct_utmp(struct logininfo *li, | |||
611 | { | 589 | { |
612 | # ifdef HAVE_ADDR_V6_IN_UTMP | 590 | # ifdef HAVE_ADDR_V6_IN_UTMP |
613 | struct sockaddr_in6 *sa6; | 591 | struct sockaddr_in6 *sa6; |
614 | # endif | 592 | # endif |
593 | |||
615 | memset(ut, '\0', sizeof(*ut)); | 594 | memset(ut, '\0', sizeof(*ut)); |
616 | 595 | ||
617 | /* First fill out fields used for both logins and logouts */ | 596 | /* First fill out fields used for both logins and logouts */ |
@@ -647,7 +626,7 @@ construct_utmp(struct logininfo *li, | |||
647 | 626 | ||
648 | /* If we're logging out, leave all other fields blank */ | 627 | /* If we're logging out, leave all other fields blank */ |
649 | if (li->type == LTYPE_LOGOUT) | 628 | if (li->type == LTYPE_LOGOUT) |
650 | return; | 629 | return; |
651 | 630 | ||
652 | /* | 631 | /* |
653 | * These fields are only used when logging in, and are blank | 632 | * These fields are only used when logging in, and are blank |
@@ -655,9 +634,11 @@ construct_utmp(struct logininfo *li, | |||
655 | */ | 634 | */ |
656 | 635 | ||
657 | /* Use strncpy because we don't necessarily want null termination */ | 636 | /* Use strncpy because we don't necessarily want null termination */ |
658 | strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username)); | 637 | strncpy(ut->ut_name, li->username, |
638 | MIN_SIZEOF(ut->ut_name, li->username)); | ||
659 | # ifdef HAVE_HOST_IN_UTMP | 639 | # ifdef HAVE_HOST_IN_UTMP |
660 | strncpy(ut->ut_host, li->hostname, MIN_SIZEOF(ut->ut_host, li->hostname)); | 640 | strncpy(ut->ut_host, li->hostname, |
641 | MIN_SIZEOF(ut->ut_host, li->hostname)); | ||
661 | # endif | 642 | # endif |
662 | # ifdef HAVE_ADDR_IN_UTMP | 643 | # ifdef HAVE_ADDR_IN_UTMP |
663 | /* this is just a 32-bit IP address */ | 644 | /* this is just a 32-bit IP address */ |
@@ -692,14 +673,12 @@ construct_utmp(struct logininfo *li, | |||
692 | void | 673 | void |
693 | set_utmpx_time(struct logininfo *li, struct utmpx *utx) | 674 | set_utmpx_time(struct logininfo *li, struct utmpx *utx) |
694 | { | 675 | { |
695 | # ifdef HAVE_TV_IN_UTMPX | 676 | # if defined(HAVE_TV_IN_UTMPX) |
696 | utx->ut_tv.tv_sec = li->tv_sec; | 677 | utx->ut_tv.tv_sec = li->tv_sec; |
697 | utx->ut_tv.tv_usec = li->tv_usec; | 678 | utx->ut_tv.tv_usec = li->tv_usec; |
698 | # else /* HAVE_TV_IN_UTMPX */ | 679 | # elif defined(HAVE_TIME_IN_UTMPX) |
699 | # ifdef HAVE_TIME_IN_UTMPX | ||
700 | utx->ut_time = li->tv_sec; | 680 | utx->ut_time = li->tv_sec; |
701 | # endif /* HAVE_TIME_IN_UTMPX */ | 681 | # endif |
702 | # endif /* HAVE_TV_IN_UTMPX */ | ||
703 | } | 682 | } |
704 | 683 | ||
705 | void | 684 | void |
@@ -709,6 +688,7 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) | |||
709 | struct sockaddr_in6 *sa6; | 688 | struct sockaddr_in6 *sa6; |
710 | # endif | 689 | # endif |
711 | memset(utx, '\0', sizeof(*utx)); | 690 | memset(utx, '\0', sizeof(*utx)); |
691 | |||
712 | # ifdef HAVE_ID_IN_UTMPX | 692 | # ifdef HAVE_ID_IN_UTMPX |
713 | line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); | 693 | line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id)); |
714 | # endif | 694 | # endif |
@@ -725,8 +705,10 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) | |||
725 | line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); | 705 | line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line)); |
726 | set_utmpx_time(li, utx); | 706 | set_utmpx_time(li, utx); |
727 | utx->ut_pid = li->pid; | 707 | utx->ut_pid = li->pid; |
708 | |||
728 | /* strncpy(): Don't necessarily want null termination */ | 709 | /* strncpy(): Don't necessarily want null termination */ |
729 | strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username)); | 710 | strncpy(utx->ut_name, li->username, |
711 | MIN_SIZEOF(utx->ut_name, li->username)); | ||
730 | 712 | ||
731 | if (li->type == LTYPE_LOGOUT) | 713 | if (li->type == LTYPE_LOGOUT) |
732 | return; | 714 | return; |
@@ -737,7 +719,8 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx) | |||
737 | */ | 719 | */ |
738 | 720 | ||
739 | # ifdef HAVE_HOST_IN_UTMPX | 721 | # ifdef HAVE_HOST_IN_UTMPX |
740 | strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname)); | 722 | strncpy(utx->ut_host, li->hostname, |
723 | MIN_SIZEOF(utx->ut_host, li->hostname)); | ||
741 | # endif | 724 | # endif |
742 | # ifdef HAVE_ADDR_IN_UTMPX | 725 | # ifdef HAVE_ADDR_IN_UTMPX |
743 | /* this is just a 32-bit IP address */ | 726 | /* this is just a 32-bit IP address */ |
@@ -785,16 +768,17 @@ utmp_write_library(struct logininfo *li, struct utmp *ut) | |||
785 | { | 768 | { |
786 | setutent(); | 769 | setutent(); |
787 | pututline(ut); | 770 | pututline(ut); |
788 | |||
789 | # ifdef HAVE_ENDUTENT | 771 | # ifdef HAVE_ENDUTENT |
790 | endutent(); | 772 | endutent(); |
791 | # endif | 773 | # endif |
792 | return 1; | 774 | return (1); |
793 | } | 775 | } |
794 | # else /* UTMP_USE_LIBRARY */ | 776 | # else /* UTMP_USE_LIBRARY */ |
795 | 777 | ||
796 | /* write a utmp entry direct to the file */ | 778 | /* |
797 | /* This is a slightly modification of code in OpenBSD's login.c */ | 779 | * Write a utmp entry direct to the file |
780 | * This is a slightly modification of code in OpenBSD's login.c | ||
781 | */ | ||
798 | static int | 782 | static int |
799 | utmp_write_direct(struct logininfo *li, struct utmp *ut) | 783 | utmp_write_direct(struct logininfo *li, struct utmp *ut) |
800 | { | 784 | { |
@@ -805,19 +789,18 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) | |||
805 | /* FIXME: (ATL) ttyslot() needs local implementation */ | 789 | /* FIXME: (ATL) ttyslot() needs local implementation */ |
806 | 790 | ||
807 | #if defined(HAVE_GETTTYENT) | 791 | #if defined(HAVE_GETTTYENT) |
808 | register struct ttyent *ty; | 792 | struct ttyent *ty; |
809 | 793 | ||
810 | tty=0; | 794 | tty=0; |
811 | |||
812 | setttyent(); | 795 | setttyent(); |
813 | while ((struct ttyent *)0 != (ty = getttyent())) { | 796 | while (NULL != (ty = getttyent())) { |
814 | tty++; | 797 | tty++; |
815 | if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) | 798 | if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line))) |
816 | break; | 799 | break; |
817 | } | 800 | } |
818 | endttyent(); | 801 | endttyent(); |
819 | 802 | ||
820 | if((struct ttyent *)0 == ty) { | 803 | if (NULL == ty) { |
821 | logit("%s: tty not found", __func__); | 804 | logit("%s: tty not found", __func__); |
822 | return (0); | 805 | return (0); |
823 | } | 806 | } |
@@ -846,11 +829,10 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) | |||
846 | * and ut_line and ut_name match, preserve the old ut_line. | 829 | * and ut_line and ut_name match, preserve the old ut_line. |
847 | */ | 830 | */ |
848 | if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && | 831 | if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) && |
849 | (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && | 832 | (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') && |
850 | (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && | 833 | (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) && |
851 | (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) { | 834 | (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) |
852 | (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); | 835 | memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host)); |
853 | } | ||
854 | 836 | ||
855 | if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { | 837 | if ((ret = lseek(fd, pos, SEEK_SET)) == -1) { |
856 | logit("%s: lseek: %s", __func__, strerror(errno)); | 838 | logit("%s: lseek: %s", __func__, strerror(errno)); |
@@ -861,14 +843,15 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut) | |||
861 | __func__, tty, UTMP_FILE); | 843 | __func__, tty, UTMP_FILE); |
862 | return (0); | 844 | return (0); |
863 | } | 845 | } |
864 | if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) | 846 | if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { |
865 | logit("%s: error writing %s: %s", __func__, | 847 | logit("%s: error writing %s: %s", __func__, |
866 | UTMP_FILE, strerror(errno)); | 848 | UTMP_FILE, strerror(errno)); |
849 | } | ||
867 | 850 | ||
868 | (void)close(fd); | 851 | close(fd); |
869 | return 1; | 852 | return (1); |
870 | } else { | 853 | } else { |
871 | return 0; | 854 | return (0); |
872 | } | 855 | } |
873 | } | 856 | } |
874 | # endif /* UTMP_USE_LIBRARY */ | 857 | # endif /* UTMP_USE_LIBRARY */ |
@@ -882,15 +865,15 @@ utmp_perform_login(struct logininfo *li) | |||
882 | # ifdef UTMP_USE_LIBRARY | 865 | # ifdef UTMP_USE_LIBRARY |
883 | if (!utmp_write_library(li, &ut)) { | 866 | if (!utmp_write_library(li, &ut)) { |
884 | logit("utmp_perform_login: utmp_write_library() failed"); | 867 | logit("utmp_perform_login: utmp_write_library() failed"); |
885 | return 0; | 868 | return (0); |
886 | } | 869 | } |
887 | # else | 870 | # else |
888 | if (!utmp_write_direct(li, &ut)) { | 871 | if (!utmp_write_direct(li, &ut)) { |
889 | logit("utmp_perform_login: utmp_write_direct() failed"); | 872 | logit("utmp_perform_login: utmp_write_direct() failed"); |
890 | return 0; | 873 | return (0); |
891 | } | 874 | } |
892 | # endif | 875 | # endif |
893 | return 1; | 876 | return (1); |
894 | } | 877 | } |
895 | 878 | ||
896 | 879 | ||
@@ -903,15 +886,15 @@ utmp_perform_logout(struct logininfo *li) | |||
903 | # ifdef UTMP_USE_LIBRARY | 886 | # ifdef UTMP_USE_LIBRARY |
904 | if (!utmp_write_library(li, &ut)) { | 887 | if (!utmp_write_library(li, &ut)) { |
905 | logit("utmp_perform_logout: utmp_write_library() failed"); | 888 | logit("utmp_perform_logout: utmp_write_library() failed"); |
906 | return 0; | 889 | return (0); |
907 | } | 890 | } |
908 | # else | 891 | # else |
909 | if (!utmp_write_direct(li, &ut)) { | 892 | if (!utmp_write_direct(li, &ut)) { |
910 | logit("utmp_perform_logout: utmp_write_direct() failed"); | 893 | logit("utmp_perform_logout: utmp_write_direct() failed"); |
911 | return 0; | 894 | return (0); |
912 | } | 895 | } |
913 | # endif | 896 | # endif |
914 | return 1; | 897 | return (1); |
915 | } | 898 | } |
916 | 899 | ||
917 | 900 | ||
@@ -920,14 +903,14 @@ utmp_write_entry(struct logininfo *li) | |||
920 | { | 903 | { |
921 | switch(li->type) { | 904 | switch(li->type) { |
922 | case LTYPE_LOGIN: | 905 | case LTYPE_LOGIN: |
923 | return utmp_perform_login(li); | 906 | return (utmp_perform_login(li)); |
924 | 907 | ||
925 | case LTYPE_LOGOUT: | 908 | case LTYPE_LOGOUT: |
926 | return utmp_perform_logout(li); | 909 | return (utmp_perform_logout(li)); |
927 | 910 | ||
928 | default: | 911 | default: |
929 | logit("utmp_write_entry: invalid type field"); | 912 | logit("utmp_write_entry: invalid type field"); |
930 | return 0; | 913 | return (0); |
931 | } | 914 | } |
932 | } | 915 | } |
933 | #endif /* USE_UTMP */ | 916 | #endif /* USE_UTMP */ |
@@ -958,7 +941,7 @@ utmpx_write_library(struct logininfo *li, struct utmpx *utx) | |||
958 | # ifdef HAVE_ENDUTXENT | 941 | # ifdef HAVE_ENDUTXENT |
959 | endutxent(); | 942 | endutxent(); |
960 | # endif | 943 | # endif |
961 | return 1; | 944 | return (1); |
962 | } | 945 | } |
963 | 946 | ||
964 | # else /* UTMPX_USE_LIBRARY */ | 947 | # else /* UTMPX_USE_LIBRARY */ |
@@ -968,7 +951,7 @@ static int | |||
968 | utmpx_write_direct(struct logininfo *li, struct utmpx *utx) | 951 | utmpx_write_direct(struct logininfo *li, struct utmpx *utx) |
969 | { | 952 | { |
970 | logit("utmpx_write_direct: not implemented!"); | 953 | logit("utmpx_write_direct: not implemented!"); |
971 | return 0; | 954 | return (0); |
972 | } | 955 | } |
973 | # endif /* UTMPX_USE_LIBRARY */ | 956 | # endif /* UTMPX_USE_LIBRARY */ |
974 | 957 | ||
@@ -981,15 +964,15 @@ utmpx_perform_login(struct logininfo *li) | |||
981 | # ifdef UTMPX_USE_LIBRARY | 964 | # ifdef UTMPX_USE_LIBRARY |
982 | if (!utmpx_write_library(li, &utx)) { | 965 | if (!utmpx_write_library(li, &utx)) { |
983 | logit("utmpx_perform_login: utmp_write_library() failed"); | 966 | logit("utmpx_perform_login: utmp_write_library() failed"); |
984 | return 0; | 967 | return (0); |
985 | } | 968 | } |
986 | # else | 969 | # else |
987 | if (!utmpx_write_direct(li, &ut)) { | 970 | if (!utmpx_write_direct(li, &ut)) { |
988 | logit("utmpx_perform_login: utmp_write_direct() failed"); | 971 | logit("utmpx_perform_login: utmp_write_direct() failed"); |
989 | return 0; | 972 | return (0); |
990 | } | 973 | } |
991 | # endif | 974 | # endif |
992 | return 1; | 975 | return (1); |
993 | } | 976 | } |
994 | 977 | ||
995 | 978 | ||
@@ -1011,7 +994,7 @@ utmpx_perform_logout(struct logininfo *li) | |||
1011 | # else | 994 | # else |
1012 | utmpx_write_direct(li, &utx); | 995 | utmpx_write_direct(li, &utx); |
1013 | # endif | 996 | # endif |
1014 | return 1; | 997 | return (1); |
1015 | } | 998 | } |
1016 | 999 | ||
1017 | int | 1000 | int |
@@ -1019,12 +1002,12 @@ utmpx_write_entry(struct logininfo *li) | |||
1019 | { | 1002 | { |
1020 | switch(li->type) { | 1003 | switch(li->type) { |
1021 | case LTYPE_LOGIN: | 1004 | case LTYPE_LOGIN: |
1022 | return utmpx_perform_login(li); | 1005 | return (utmpx_perform_login(li)); |
1023 | case LTYPE_LOGOUT: | 1006 | case LTYPE_LOGOUT: |
1024 | return utmpx_perform_logout(li); | 1007 | return (utmpx_perform_logout(li)); |
1025 | default: | 1008 | default: |
1026 | logit("utmpx_write_entry: invalid type field"); | 1009 | logit("utmpx_write_entry: invalid type field"); |
1027 | return 0; | 1010 | return (0); |
1028 | } | 1011 | } |
1029 | } | 1012 | } |
1030 | #endif /* USE_UTMPX */ | 1013 | #endif /* USE_UTMPX */ |
@@ -1036,8 +1019,10 @@ utmpx_write_entry(struct logininfo *li) | |||
1036 | 1019 | ||
1037 | #ifdef USE_WTMP | 1020 | #ifdef USE_WTMP |
1038 | 1021 | ||
1039 | /* write a wtmp entry direct to the end of the file */ | 1022 | /* |
1040 | /* This is a slight modification of code in OpenBSD's logwtmp.c */ | 1023 | * Write a wtmp entry direct to the end of the file |
1024 | * This is a slight modification of code in OpenBSD's logwtmp.c | ||
1025 | */ | ||
1041 | static int | 1026 | static int |
1042 | wtmp_write(struct logininfo *li, struct utmp *ut) | 1027 | wtmp_write(struct logininfo *li, struct utmp *ut) |
1043 | { | 1028 | { |
@@ -1047,7 +1032,7 @@ wtmp_write(struct logininfo *li, struct utmp *ut) | |||
1047 | if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { | 1032 | if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) { |
1048 | logit("wtmp_write: problem writing %s: %s", | 1033 | logit("wtmp_write: problem writing %s: %s", |
1049 | WTMP_FILE, strerror(errno)); | 1034 | WTMP_FILE, strerror(errno)); |
1050 | return 0; | 1035 | return (0); |
1051 | } | 1036 | } |
1052 | if (fstat(fd, &buf) == 0) | 1037 | if (fstat(fd, &buf) == 0) |
1053 | if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { | 1038 | if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) { |
@@ -1056,8 +1041,8 @@ wtmp_write(struct logininfo *li, struct utmp *ut) | |||
1056 | WTMP_FILE, strerror(errno)); | 1041 | WTMP_FILE, strerror(errno)); |
1057 | ret = 0; | 1042 | ret = 0; |
1058 | } | 1043 | } |
1059 | (void)close(fd); | 1044 | close(fd); |
1060 | return ret; | 1045 | return (ret); |
1061 | } | 1046 | } |
1062 | 1047 | ||
1063 | static int | 1048 | static int |
@@ -1066,7 +1051,7 @@ wtmp_perform_login(struct logininfo *li) | |||
1066 | struct utmp ut; | 1051 | struct utmp ut; |
1067 | 1052 | ||
1068 | construct_utmp(li, &ut); | 1053 | construct_utmp(li, &ut); |
1069 | return wtmp_write(li, &ut); | 1054 | return (wtmp_write(li, &ut)); |
1070 | } | 1055 | } |
1071 | 1056 | ||
1072 | 1057 | ||
@@ -1076,7 +1061,7 @@ wtmp_perform_logout(struct logininfo *li) | |||
1076 | struct utmp ut; | 1061 | struct utmp ut; |
1077 | 1062 | ||
1078 | construct_utmp(li, &ut); | 1063 | construct_utmp(li, &ut); |
1079 | return wtmp_write(li, &ut); | 1064 | return (wtmp_write(li, &ut)); |
1080 | } | 1065 | } |
1081 | 1066 | ||
1082 | 1067 | ||
@@ -1085,17 +1070,18 @@ wtmp_write_entry(struct logininfo *li) | |||
1085 | { | 1070 | { |
1086 | switch(li->type) { | 1071 | switch(li->type) { |
1087 | case LTYPE_LOGIN: | 1072 | case LTYPE_LOGIN: |
1088 | return wtmp_perform_login(li); | 1073 | return (wtmp_perform_login(li)); |
1089 | case LTYPE_LOGOUT: | 1074 | case LTYPE_LOGOUT: |
1090 | return wtmp_perform_logout(li); | 1075 | return (wtmp_perform_logout(li)); |
1091 | default: | 1076 | default: |
1092 | logit("wtmp_write_entry: invalid type field"); | 1077 | logit("wtmp_write_entry: invalid type field"); |
1093 | return 0; | 1078 | return (0); |
1094 | } | 1079 | } |
1095 | } | 1080 | } |
1096 | 1081 | ||
1097 | 1082 | ||
1098 | /* Notes on fetching login data from wtmp/wtmpx | 1083 | /* |
1084 | * Notes on fetching login data from wtmp/wtmpx | ||
1099 | * | 1085 | * |
1100 | * Logouts are usually recorded with (amongst other things) a blank | 1086 | * Logouts are usually recorded with (amongst other things) a blank |
1101 | * username on a given tty line. However, some systems (HP-UX is one) | 1087 | * username on a given tty line. However, some systems (HP-UX is one) |
@@ -1116,15 +1102,15 @@ static int | |||
1116 | wtmp_islogin(struct logininfo *li, struct utmp *ut) | 1102 | wtmp_islogin(struct logininfo *li, struct utmp *ut) |
1117 | { | 1103 | { |
1118 | if (strncmp(li->username, ut->ut_name, | 1104 | if (strncmp(li->username, ut->ut_name, |
1119 | MIN_SIZEOF(li->username, ut->ut_name)) == 0) { | 1105 | MIN_SIZEOF(li->username, ut->ut_name)) == 0) { |
1120 | # ifdef HAVE_TYPE_IN_UTMP | 1106 | # ifdef HAVE_TYPE_IN_UTMP |
1121 | if (ut->ut_type & USER_PROCESS) | 1107 | if (ut->ut_type & USER_PROCESS) |
1122 | return 1; | 1108 | return (1); |
1123 | # else | 1109 | # else |
1124 | return 1; | 1110 | return (1); |
1125 | # endif | 1111 | # endif |
1126 | } | 1112 | } |
1127 | return 0; | 1113 | return (0); |
1128 | } | 1114 | } |
1129 | 1115 | ||
1130 | int | 1116 | int |
@@ -1132,7 +1118,7 @@ wtmp_get_entry(struct logininfo *li) | |||
1132 | { | 1118 | { |
1133 | struct stat st; | 1119 | struct stat st; |
1134 | struct utmp ut; | 1120 | struct utmp ut; |
1135 | int fd, found=0; | 1121 | int fd, found = 0; |
1136 | 1122 | ||
1137 | /* Clear the time entries in our logininfo */ | 1123 | /* Clear the time entries in our logininfo */ |
1138 | li->tv_sec = li->tv_usec = 0; | 1124 | li->tv_sec = li->tv_usec = 0; |
@@ -1140,20 +1126,20 @@ wtmp_get_entry(struct logininfo *li) | |||
1140 | if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { | 1126 | if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) { |
1141 | logit("wtmp_get_entry: problem opening %s: %s", | 1127 | logit("wtmp_get_entry: problem opening %s: %s", |
1142 | WTMP_FILE, strerror(errno)); | 1128 | WTMP_FILE, strerror(errno)); |
1143 | return 0; | 1129 | return (0); |
1144 | } | 1130 | } |
1145 | if (fstat(fd, &st) != 0) { | 1131 | if (fstat(fd, &st) != 0) { |
1146 | logit("wtmp_get_entry: couldn't stat %s: %s", | 1132 | logit("wtmp_get_entry: couldn't stat %s: %s", |
1147 | WTMP_FILE, strerror(errno)); | 1133 | WTMP_FILE, strerror(errno)); |
1148 | close(fd); | 1134 | close(fd); |
1149 | return 0; | 1135 | return (0); |
1150 | } | 1136 | } |
1151 | 1137 | ||
1152 | /* Seek to the start of the last struct utmp */ | 1138 | /* Seek to the start of the last struct utmp */ |
1153 | if (lseek(fd, -(off_t)sizeof(struct utmp), SEEK_END) == -1) { | 1139 | if (lseek(fd, -(off_t)sizeof(struct utmp), SEEK_END) == -1) { |
1154 | /* Looks like we've got a fresh wtmp file */ | 1140 | /* Looks like we've got a fresh wtmp file */ |
1155 | close(fd); | 1141 | close(fd); |
1156 | return 0; | 1142 | return (0); |
1157 | } | 1143 | } |
1158 | 1144 | ||
1159 | while (!found) { | 1145 | while (!found) { |
@@ -1161,12 +1147,14 @@ wtmp_get_entry(struct logininfo *li) | |||
1161 | logit("wtmp_get_entry: read of %s failed: %s", | 1147 | logit("wtmp_get_entry: read of %s failed: %s", |
1162 | WTMP_FILE, strerror(errno)); | 1148 | WTMP_FILE, strerror(errno)); |
1163 | close (fd); | 1149 | close (fd); |
1164 | return 0; | 1150 | return (0); |
1165 | } | 1151 | } |
1166 | if ( wtmp_islogin(li, &ut) ) { | 1152 | if ( wtmp_islogin(li, &ut) ) { |
1167 | found = 1; | 1153 | found = 1; |
1168 | /* We've already checked for a time in struct | 1154 | /* |
1169 | * utmp, in login_getlast(). */ | 1155 | * We've already checked for a time in struct |
1156 | * utmp, in login_getlast() | ||
1157 | */ | ||
1170 | # ifdef HAVE_TIME_IN_UTMP | 1158 | # ifdef HAVE_TIME_IN_UTMP |
1171 | li->tv_sec = ut.ut_time; | 1159 | li->tv_sec = ut.ut_time; |
1172 | # else | 1160 | # else |
@@ -1175,24 +1163,24 @@ wtmp_get_entry(struct logininfo *li) | |||
1175 | # endif | 1163 | # endif |
1176 | # endif | 1164 | # endif |
1177 | line_fullname(li->line, ut.ut_line, | 1165 | line_fullname(li->line, ut.ut_line, |
1178 | MIN_SIZEOF(li->line, ut.ut_line)); | 1166 | MIN_SIZEOF(li->line, ut.ut_line)); |
1179 | # ifdef HAVE_HOST_IN_UTMP | 1167 | # ifdef HAVE_HOST_IN_UTMP |
1180 | strlcpy(li->hostname, ut.ut_host, | 1168 | strlcpy(li->hostname, ut.ut_host, |
1181 | MIN_SIZEOF(li->hostname, ut.ut_host)); | 1169 | MIN_SIZEOF(li->hostname, ut.ut_host)); |
1182 | # endif | 1170 | # endif |
1183 | continue; | 1171 | continue; |
1184 | } | 1172 | } |
1185 | /* Seek back 2 x struct utmp */ | 1173 | /* Seek back 2 x struct utmp */ |
1186 | if (lseek(fd, -(off_t)(2 * sizeof(struct utmp)), SEEK_CUR) == -1) { | 1174 | if (lseek(fd, -(off_t)(2 * sizeof(struct utmp)), SEEK_CUR) == -1) { |
1187 | /* We've found the start of the file, so quit */ | 1175 | /* We've found the start of the file, so quit */ |
1188 | close (fd); | 1176 | close(fd); |
1189 | return 0; | 1177 | return (0); |
1190 | } | 1178 | } |
1191 | } | 1179 | } |
1192 | 1180 | ||
1193 | /* We found an entry. Tidy up and return */ | 1181 | /* We found an entry. Tidy up and return */ |
1194 | close(fd); | 1182 | close(fd); |
1195 | return 1; | 1183 | return (1); |
1196 | } | 1184 | } |
1197 | # endif /* USE_WTMP */ | 1185 | # endif /* USE_WTMP */ |
1198 | 1186 | ||
@@ -1202,8 +1190,10 @@ wtmp_get_entry(struct logininfo *li) | |||
1202 | **/ | 1190 | **/ |
1203 | 1191 | ||
1204 | #ifdef USE_WTMPX | 1192 | #ifdef USE_WTMPX |
1205 | /* write a wtmpx entry direct to the end of the file */ | 1193 | /* |
1206 | /* This is a slight modification of code in OpenBSD's logwtmp.c */ | 1194 | * Write a wtmpx entry direct to the end of the file |
1195 | * This is a slight modification of code in OpenBSD's logwtmp.c | ||
1196 | */ | ||
1207 | static int | 1197 | static int |
1208 | wtmpx_write(struct logininfo *li, struct utmpx *utx) | 1198 | wtmpx_write(struct logininfo *li, struct utmpx *utx) |
1209 | { | 1199 | { |
@@ -1214,7 +1204,7 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx) | |||
1214 | if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { | 1204 | if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) { |
1215 | logit("wtmpx_write: problem opening %s: %s", | 1205 | logit("wtmpx_write: problem opening %s: %s", |
1216 | WTMPX_FILE, strerror(errno)); | 1206 | WTMPX_FILE, strerror(errno)); |
1217 | return 0; | 1207 | return (0); |
1218 | } | 1208 | } |
1219 | 1209 | ||
1220 | if (fstat(fd, &buf) == 0) | 1210 | if (fstat(fd, &buf) == 0) |
@@ -1224,12 +1214,12 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx) | |||
1224 | WTMPX_FILE, strerror(errno)); | 1214 | WTMPX_FILE, strerror(errno)); |
1225 | ret = 0; | 1215 | ret = 0; |
1226 | } | 1216 | } |
1227 | (void)close(fd); | 1217 | close(fd); |
1228 | 1218 | ||
1229 | return ret; | 1219 | return (ret); |
1230 | #else | 1220 | #else |
1231 | updwtmpx(WTMPX_FILE, utx); | 1221 | updwtmpx(WTMPX_FILE, utx); |
1232 | return 1; | 1222 | return (1); |
1233 | #endif | 1223 | #endif |
1234 | } | 1224 | } |
1235 | 1225 | ||
@@ -1240,7 +1230,7 @@ wtmpx_perform_login(struct logininfo *li) | |||
1240 | struct utmpx utx; | 1230 | struct utmpx utx; |
1241 | 1231 | ||
1242 | construct_utmpx(li, &utx); | 1232 | construct_utmpx(li, &utx); |
1243 | return wtmpx_write(li, &utx); | 1233 | return (wtmpx_write(li, &utx)); |
1244 | } | 1234 | } |
1245 | 1235 | ||
1246 | 1236 | ||
@@ -1250,7 +1240,7 @@ wtmpx_perform_logout(struct logininfo *li) | |||
1250 | struct utmpx utx; | 1240 | struct utmpx utx; |
1251 | 1241 | ||
1252 | construct_utmpx(li, &utx); | 1242 | construct_utmpx(li, &utx); |
1253 | return wtmpx_write(li, &utx); | 1243 | return (wtmpx_write(li, &utx)); |
1254 | } | 1244 | } |
1255 | 1245 | ||
1256 | 1246 | ||
@@ -1259,12 +1249,12 @@ wtmpx_write_entry(struct logininfo *li) | |||
1259 | { | 1249 | { |
1260 | switch(li->type) { | 1250 | switch(li->type) { |
1261 | case LTYPE_LOGIN: | 1251 | case LTYPE_LOGIN: |
1262 | return wtmpx_perform_login(li); | 1252 | return (wtmpx_perform_login(li)); |
1263 | case LTYPE_LOGOUT: | 1253 | case LTYPE_LOGOUT: |
1264 | return wtmpx_perform_logout(li); | 1254 | return (wtmpx_perform_logout(li)); |
1265 | default: | 1255 | default: |
1266 | logit("wtmpx_write_entry: invalid type field"); | 1256 | logit("wtmpx_write_entry: invalid type field"); |
1267 | return 0; | 1257 | return (0); |
1268 | } | 1258 | } |
1269 | } | 1259 | } |
1270 | 1260 | ||
@@ -1275,16 +1265,16 @@ wtmpx_write_entry(struct logininfo *li) | |||
1275 | static int | 1265 | static int |
1276 | wtmpx_islogin(struct logininfo *li, struct utmpx *utx) | 1266 | wtmpx_islogin(struct logininfo *li, struct utmpx *utx) |
1277 | { | 1267 | { |
1278 | if ( strncmp(li->username, utx->ut_name, | 1268 | if (strncmp(li->username, utx->ut_name, |
1279 | MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) { | 1269 | MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) { |
1280 | # ifdef HAVE_TYPE_IN_UTMPX | 1270 | # ifdef HAVE_TYPE_IN_UTMPX |
1281 | if (utx->ut_type == USER_PROCESS) | 1271 | if (utx->ut_type == USER_PROCESS) |
1282 | return 1; | 1272 | return (1); |
1283 | # else | 1273 | # else |
1284 | return 1; | 1274 | return (1); |
1285 | # endif | 1275 | # endif |
1286 | } | 1276 | } |
1287 | return 0; | 1277 | return (0); |
1288 | } | 1278 | } |
1289 | 1279 | ||
1290 | 1280 | ||
@@ -1301,20 +1291,20 @@ wtmpx_get_entry(struct logininfo *li) | |||
1301 | if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { | 1291 | if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) { |
1302 | logit("wtmpx_get_entry: problem opening %s: %s", | 1292 | logit("wtmpx_get_entry: problem opening %s: %s", |
1303 | WTMPX_FILE, strerror(errno)); | 1293 | WTMPX_FILE, strerror(errno)); |
1304 | return 0; | 1294 | return (0); |
1305 | } | 1295 | } |
1306 | if (fstat(fd, &st) != 0) { | 1296 | if (fstat(fd, &st) != 0) { |
1307 | logit("wtmpx_get_entry: couldn't stat %s: %s", | 1297 | logit("wtmpx_get_entry: couldn't stat %s: %s", |
1308 | WTMPX_FILE, strerror(errno)); | 1298 | WTMPX_FILE, strerror(errno)); |
1309 | close(fd); | 1299 | close(fd); |
1310 | return 0; | 1300 | return (0); |
1311 | } | 1301 | } |
1312 | 1302 | ||
1313 | /* Seek to the start of the last struct utmpx */ | 1303 | /* Seek to the start of the last struct utmpx */ |
1314 | if (lseek(fd, -(off_t)sizeof(struct utmpx), SEEK_END) == -1 ) { | 1304 | if (lseek(fd, -(off_t)sizeof(struct utmpx), SEEK_END) == -1 ) { |
1315 | /* probably a newly rotated wtmpx file */ | 1305 | /* probably a newly rotated wtmpx file */ |
1316 | close(fd); | 1306 | close(fd); |
1317 | return 0; | 1307 | return (0); |
1318 | } | 1308 | } |
1319 | 1309 | ||
1320 | while (!found) { | 1310 | while (!found) { |
@@ -1322,34 +1312,34 @@ wtmpx_get_entry(struct logininfo *li) | |||
1322 | logit("wtmpx_get_entry: read of %s failed: %s", | 1312 | logit("wtmpx_get_entry: read of %s failed: %s", |
1323 | WTMPX_FILE, strerror(errno)); | 1313 | WTMPX_FILE, strerror(errno)); |
1324 | close (fd); | 1314 | close (fd); |
1325 | return 0; | 1315 | return (0); |
1326 | } | 1316 | } |
1327 | /* Logouts are recorded as a blank username on a particular line. | 1317 | /* |
1328 | * So, we just need to find the username in struct utmpx */ | 1318 | * Logouts are recorded as a blank username on a particular |
1329 | if ( wtmpx_islogin(li, &utx) ) { | 1319 | * line. So, we just need to find the username in struct utmpx |
1320 | */ | ||
1321 | if (wtmpx_islogin(li, &utx)) { | ||
1330 | found = 1; | 1322 | found = 1; |
1331 | # ifdef HAVE_TV_IN_UTMPX | 1323 | # if defined(HAVE_TV_IN_UTMPX) |
1332 | li->tv_sec = utx.ut_tv.tv_sec; | 1324 | li->tv_sec = utx.ut_tv.tv_sec; |
1333 | # else | 1325 | # elif defined(HAVE_TIME_IN_UTMPX) |
1334 | # ifdef HAVE_TIME_IN_UTMPX | ||
1335 | li->tv_sec = utx.ut_time; | 1326 | li->tv_sec = utx.ut_time; |
1336 | # endif | ||
1337 | # endif | 1327 | # endif |
1338 | line_fullname(li->line, utx.ut_line, sizeof(li->line)); | 1328 | line_fullname(li->line, utx.ut_line, sizeof(li->line)); |
1339 | # ifdef HAVE_HOST_IN_UTMPX | 1329 | # if defined(HAVE_HOST_IN_UTMPX) |
1340 | strlcpy(li->hostname, utx.ut_host, | 1330 | strlcpy(li->hostname, utx.ut_host, |
1341 | MIN_SIZEOF(li->hostname, utx.ut_host)); | 1331 | MIN_SIZEOF(li->hostname, utx.ut_host)); |
1342 | # endif | 1332 | # endif |
1343 | continue; | 1333 | continue; |
1344 | } | 1334 | } |
1345 | if (lseek(fd, -(off_t)(2 * sizeof(struct utmpx)), SEEK_CUR) == -1) { | 1335 | if (lseek(fd, -(off_t)(2 * sizeof(struct utmpx)), SEEK_CUR) == -1) { |
1346 | close (fd); | 1336 | close(fd); |
1347 | return 0; | 1337 | return (0); |
1348 | } | 1338 | } |
1349 | } | 1339 | } |
1350 | 1340 | ||
1351 | close(fd); | 1341 | close(fd); |
1352 | return 1; | 1342 | return (1); |
1353 | } | 1343 | } |
1354 | #endif /* USE_WTMPX */ | 1344 | #endif /* USE_WTMPX */ |
1355 | 1345 | ||
@@ -1363,15 +1353,15 @@ syslogin_perform_login(struct logininfo *li) | |||
1363 | { | 1353 | { |
1364 | struct utmp *ut; | 1354 | struct utmp *ut; |
1365 | 1355 | ||
1366 | if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) { | 1356 | if ((ut = (struct utmp *)malloc(sizeof(*ut))) == NULL) { |
1367 | logit("syslogin_perform_login: couldn't malloc()"); | 1357 | logit("syslogin_perform_login: couldn't malloc()"); |
1368 | return 0; | 1358 | return (0); |
1369 | } | 1359 | } |
1370 | construct_utmp(li, ut); | 1360 | construct_utmp(li, ut); |
1371 | login(ut); | 1361 | login(ut); |
1372 | free(ut); | 1362 | free(ut); |
1373 | 1363 | ||
1374 | return 1; | 1364 | return (1); |
1375 | } | 1365 | } |
1376 | 1366 | ||
1377 | static int | 1367 | static int |
@@ -1382,19 +1372,18 @@ syslogin_perform_logout(struct logininfo *li) | |||
1382 | 1372 | ||
1383 | (void)line_stripname(line, li->line, sizeof(line)); | 1373 | (void)line_stripname(line, li->line, sizeof(line)); |
1384 | 1374 | ||
1385 | if (!logout(line)) { | 1375 | if (!logout(line)) |
1386 | logit("syslogin_perform_logout: logout() returned an error"); | 1376 | logit("syslogin_perform_logout: logout() returned an error"); |
1387 | # ifdef HAVE_LOGWTMP | 1377 | # ifdef HAVE_LOGWTMP |
1388 | } else { | 1378 | else |
1389 | logwtmp(line, "", ""); | 1379 | logwtmp(line, "", ""); |
1390 | # endif | 1380 | # endif |
1391 | } | ||
1392 | /* FIXME: (ATL - if the need arises) What to do if we have | 1381 | /* FIXME: (ATL - if the need arises) What to do if we have |
1393 | * login, but no logout? what if logout but no logwtmp? All | 1382 | * login, but no logout? what if logout but no logwtmp? All |
1394 | * routines are in libutil so they should all be there, | 1383 | * routines are in libutil so they should all be there, |
1395 | * but... */ | 1384 | * but... */ |
1396 | # endif | 1385 | # endif |
1397 | return 1; | 1386 | return (1); |
1398 | } | 1387 | } |
1399 | 1388 | ||
1400 | int | 1389 | int |
@@ -1402,12 +1391,12 @@ syslogin_write_entry(struct logininfo *li) | |||
1402 | { | 1391 | { |
1403 | switch (li->type) { | 1392 | switch (li->type) { |
1404 | case LTYPE_LOGIN: | 1393 | case LTYPE_LOGIN: |
1405 | return syslogin_perform_login(li); | 1394 | return (syslogin_perform_login(li)); |
1406 | case LTYPE_LOGOUT: | 1395 | case LTYPE_LOGOUT: |
1407 | return syslogin_perform_logout(li); | 1396 | return (syslogin_perform_logout(li)); |
1408 | default: | 1397 | default: |
1409 | logit("syslogin_write_entry: Invalid type field"); | 1398 | logit("syslogin_write_entry: Invalid type field"); |
1410 | return 0; | 1399 | return (0); |
1411 | } | 1400 | } |
1412 | } | 1401 | } |
1413 | #endif /* USE_LOGIN */ | 1402 | #endif /* USE_LOGIN */ |
@@ -1429,7 +1418,7 @@ lastlog_construct(struct logininfo *li, struct lastlog *last) | |||
1429 | /* clear the structure */ | 1418 | /* clear the structure */ |
1430 | memset(last, '\0', sizeof(*last)); | 1419 | memset(last, '\0', sizeof(*last)); |
1431 | 1420 | ||
1432 | (void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); | 1421 | line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); |
1433 | strlcpy(last->ll_host, li->hostname, | 1422 | strlcpy(last->ll_host, li->hostname, |
1434 | MIN_SIZEOF(last->ll_host, li->hostname)); | 1423 | MIN_SIZEOF(last->ll_host, li->hostname)); |
1435 | last->ll_time = li->tv_sec; | 1424 | last->ll_time = li->tv_sec; |
@@ -1441,16 +1430,16 @@ lastlog_filetype(char *filename) | |||
1441 | struct stat st; | 1430 | struct stat st; |
1442 | 1431 | ||
1443 | if (stat(LASTLOG_FILE, &st) != 0) { | 1432 | if (stat(LASTLOG_FILE, &st) != 0) { |
1444 | logit("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE, | 1433 | logit("lastlog_perform_login: Couldn't stat %s: %s", |
1445 | strerror(errno)); | 1434 | LASTLOG_FILE, strerror(errno)); |
1446 | return 0; | 1435 | return (0); |
1447 | } | 1436 | } |
1448 | if (S_ISDIR(st.st_mode)) | 1437 | if (S_ISDIR(st.st_mode)) |
1449 | return LL_DIR; | 1438 | return (LL_DIR); |
1450 | else if (S_ISREG(st.st_mode)) | 1439 | else if (S_ISREG(st.st_mode)) |
1451 | return LL_FILE; | 1440 | return (LL_FILE); |
1452 | else | 1441 | else |
1453 | return LL_OTHER; | 1442 | return (LL_OTHER); |
1454 | } | 1443 | } |
1455 | 1444 | ||
1456 | 1445 | ||
@@ -1464,38 +1453,39 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) | |||
1464 | 1453 | ||
1465 | type = lastlog_filetype(LASTLOG_FILE); | 1454 | type = lastlog_filetype(LASTLOG_FILE); |
1466 | switch (type) { | 1455 | switch (type) { |
1467 | case LL_FILE: | 1456 | case LL_FILE: |
1468 | strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); | 1457 | strlcpy(lastlog_file, LASTLOG_FILE, |
1469 | break; | 1458 | sizeof(lastlog_file)); |
1470 | case LL_DIR: | 1459 | break; |
1471 | snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", | 1460 | case LL_DIR: |
1472 | LASTLOG_FILE, li->username); | 1461 | snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", |
1473 | break; | 1462 | LASTLOG_FILE, li->username); |
1474 | default: | 1463 | break; |
1475 | logit("lastlog_openseek: %.100s is not a file or directory!", | 1464 | default: |
1476 | LASTLOG_FILE); | 1465 | logit("lastlog_openseek: %.100s is not a file or directory!", |
1477 | return 0; | 1466 | LASTLOG_FILE); |
1467 | return (0); | ||
1478 | } | 1468 | } |
1479 | 1469 | ||
1480 | *fd = open(lastlog_file, filemode, 0600); | 1470 | *fd = open(lastlog_file, filemode, 0600); |
1481 | if ( *fd < 0) { | 1471 | if (*fd < 0) { |
1482 | debug("lastlog_openseek: Couldn't open %s: %s", | 1472 | debug("lastlog_openseek: Couldn't open %s: %s", |
1483 | lastlog_file, strerror(errno)); | 1473 | lastlog_file, strerror(errno)); |
1484 | return 0; | 1474 | return (0); |
1485 | } | 1475 | } |
1486 | 1476 | ||
1487 | if (type == LL_FILE) { | 1477 | if (type == LL_FILE) { |
1488 | /* find this uid's offset in the lastlog file */ | 1478 | /* find this uid's offset in the lastlog file */ |
1489 | offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); | 1479 | offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); |
1490 | 1480 | ||
1491 | if ( lseek(*fd, offset, SEEK_SET) != offset ) { | 1481 | if (lseek(*fd, offset, SEEK_SET) != offset) { |
1492 | logit("lastlog_openseek: %s->lseek(): %s", | 1482 | logit("lastlog_openseek: %s->lseek(): %s", |
1493 | lastlog_file, strerror(errno)); | 1483 | lastlog_file, strerror(errno)); |
1494 | return 0; | 1484 | return (0); |
1495 | } | 1485 | } |
1496 | } | 1486 | } |
1497 | 1487 | ||
1498 | return 1; | 1488 | return (1); |
1499 | } | 1489 | } |
1500 | 1490 | ||
1501 | static int | 1491 | static int |
@@ -1508,18 +1498,18 @@ lastlog_perform_login(struct logininfo *li) | |||
1508 | lastlog_construct(li, &last); | 1498 | lastlog_construct(li, &last); |
1509 | 1499 | ||
1510 | if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) | 1500 | if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) |
1511 | return(0); | 1501 | return (0); |
1512 | 1502 | ||
1513 | /* write the entry */ | 1503 | /* write the entry */ |
1514 | if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { | 1504 | if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { |
1515 | close(fd); | 1505 | close(fd); |
1516 | logit("lastlog_write_filemode: Error writing to %s: %s", | 1506 | logit("lastlog_write_filemode: Error writing to %s: %s", |
1517 | LASTLOG_FILE, strerror(errno)); | 1507 | LASTLOG_FILE, strerror(errno)); |
1518 | return 0; | 1508 | return (0); |
1519 | } | 1509 | } |
1520 | 1510 | ||
1521 | close(fd); | 1511 | close(fd); |
1522 | return 1; | 1512 | return (1); |
1523 | } | 1513 | } |
1524 | 1514 | ||
1525 | int | 1515 | int |
@@ -1527,10 +1517,10 @@ lastlog_write_entry(struct logininfo *li) | |||
1527 | { | 1517 | { |
1528 | switch(li->type) { | 1518 | switch(li->type) { |
1529 | case LTYPE_LOGIN: | 1519 | case LTYPE_LOGIN: |
1530 | return lastlog_perform_login(li); | 1520 | return (lastlog_perform_login(li)); |
1531 | default: | 1521 | default: |
1532 | logit("lastlog_write_entry: Invalid type field"); | 1522 | logit("lastlog_write_entry: Invalid type field"); |
1533 | return 0; | 1523 | return (0); |
1534 | } | 1524 | } |
1535 | } | 1525 | } |
1536 | 1526 | ||
@@ -1539,7 +1529,7 @@ lastlog_populate_entry(struct logininfo *li, struct lastlog *last) | |||
1539 | { | 1529 | { |
1540 | line_fullname(li->line, last->ll_line, sizeof(li->line)); | 1530 | line_fullname(li->line, last->ll_line, sizeof(li->line)); |
1541 | strlcpy(li->hostname, last->ll_host, | 1531 | strlcpy(li->hostname, last->ll_host, |
1542 | MIN_SIZEOF(li->hostname, last->ll_host)); | 1532 | MIN_SIZEOF(li->hostname, last->ll_host)); |
1543 | li->tv_sec = last->ll_time; | 1533 | li->tv_sec = last->ll_time; |
1544 | } | 1534 | } |
1545 | 1535 | ||