* libmisc/failure.c: Check return values. If lseek() failed, avoid

reading or writing at an unspecified location. Log to syslog in
	case of failure when reading a faillog entry or writing in
	faillog or btmp.
	* libmisc/failure.c: Check if the file exist before opening it.
	* libmisc/failure.c: Log failures of open() and close() when
	necessary.
This commit is contained in:
nekral-guest 2008-06-14 23:38:43 +00:00
parent 0afd6a8312
commit 1b631c42ef
2 changed files with 79 additions and 28 deletions

View File

@ -1,3 +1,13 @@
2008-06-15 Nicolas François <nicolas.francois@centraliens.net>
* libmisc/failure.c: Check return values. If lseek() failed, avoid
reading or writing at an unspecified location. Log to syslog in
case of failure when reading a faillog entry or writing in
faillog or btmp.
* libmisc/failure.c: Check if the file exist before opening it.
* libmisc/failure.c: Log failures of open() and close() when
necessary.
2008-06-14 Nicolas François <nicolas.francois@centraliens.net> 2008-06-14 Nicolas François <nicolas.francois@centraliens.net>
* lib/prototypes.h: Add the getrange() prototype. * lib/prototypes.h: Add the getrange() prototype.

View File

@ -36,6 +36,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include "defines.h" #include "defines.h"
#include "faillog.h" #include "faillog.h"
#include "getdef.h" #include "getdef.h"
@ -50,13 +51,21 @@
void failure (uid_t uid, const char *tty, struct faillog *fl) void failure (uid_t uid, const char *tty, struct faillog *fl)
{ {
int fd; int fd;
off_t offset_uid = (off_t) (sizeof *fl) * uid;
/* /*
* Don't do anything if failure logging isn't set up. * Don't do anything if failure logging isn't set up.
*/ */
/* TODO: check if the file exists */
if (access (FAILLOG_FILE, F_OK) != 0) {
return;
}
fd = open (FAILLOG_FILE, O_RDWR); fd = open (FAILLOG_FILE, O_RDWR);
if (fd < 0) { if (fd < 0) {
SYSLOG ((LOG_WARN,
"Can't write faillog entry for UID %lu in %s.",
(unsigned long) uid, FAILLOG_FILE));
return; return;
} }
@ -66,9 +75,15 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
* share just about everything else ... * share just about everything else ...
*/ */
lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET); if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
/* TODO: check failures */ || (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
if (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl) { /* This is not necessarily a failure. The file is
* initially zero length.
*
* If lseek() or read() failed for any other reason, this
* might reset the counter. But the new failure will be
* logged.
*/
memzero (fl, sizeof *fl); memzero (fl, sizeof *fl);
} }
@ -93,12 +108,13 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
* seem that great. * seem that great.
*/ */
lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET); if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
/* TODO: check failures */ || (write (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)
write (fd, (char *) fl, sizeof *fl); || (close (fd) != 0)) {
/* TODO: log failures */ SYSLOG ((LOG_WARN,
close (fd); "Can't write faillog entry for UID %lu in %s.",
/* TODO: log failures */ (unsigned long) uid, FAILLOG_FILE));
}
} }
static bool too_many_failures (const struct faillog *fl) static bool too_many_failures (const struct faillog *fl)
@ -137,14 +153,22 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
{ {
int fd; int fd;
struct faillog fail; struct faillog fail;
off_t offset_uid = (off_t) (sizeof *fl) * uid;
/* /*
* Suppress the check if the log file isn't there. * Suppress the check if the log file isn't there.
*/ */
/* TODO: check if the file exists */ if (access (FAILLOG_FILE, F_OK) != 0) {
fd = open (FAILLOG_FILE, O_RDWR); return 1;
}
fd = open (FAILLOG_FILE, failed?O_RDONLY:O_RDWR);
if (fd < 0) { if (fd < 0) {
SYSLOG ((LOG_WARN,
"Can't open the faillog file (%s) to check UID %lu. "
"User access authorized.",
FAILLOG_FILE, (unsigned long) uid));
return 1; return 1;
} }
@ -160,14 +184,14 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
* no need to reset the count. * no need to reset the count.
*/ */
lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET); if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
if (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl) { || (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
close (fd); (void) close (fd);
return 1; return 1;
} }
if (too_many_failures (fl)) { if (too_many_failures (fl)) {
close (fd); (void) close (fd);
return 0; return 0;
} }
@ -182,10 +206,17 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
fail = *fl; fail = *fl;
fail.fail_cnt = 0; fail.fail_cnt = 0;
lseek (fd, (off_t) sizeof fail * uid, SEEK_SET); if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
write (fd, (char *) &fail, sizeof fail); || (write (fd, (const void *) &fail, sizeof fail) != (ssize_t) sizeof fail)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't reset faillog entry for UID %lu in %s.",
(unsigned long) uid, FAILLOG_FILE));
}
} else {
(void) close (fd);
} }
close (fd);
return 1; return 1;
} }
@ -241,11 +272,11 @@ void failprint (const struct faillog *fail)
} }
#endif #endif
printf (ngettext ("%d failure since last login.\n" printf (ngettext ("%d failure since last login.\n"
"Last was %s on %s.\n", "Last was %s on %s.\n",
"%d failures since last login.\n" "%d failures since last login.\n"
"Last was %s on %s.\n", "Last was %s on %s.\n",
fail->fail_cnt), (unsigned long) fail->fail_cnt),
fail->fail_cnt, lasttime, fail->fail_line); fail->fail_cnt, lasttime, fail->fail_line);
} }
/* /*
@ -281,17 +312,27 @@ void failtmp (
* feature to be used. * feature to be used.
*/ */
if (access (ftmp, F_OK) != 0) {
return;
}
fd = open (ftmp, O_WRONLY | O_APPEND); fd = open (ftmp, O_WRONLY | O_APPEND);
if (-1 == fd) { if (-1 == fd) {
SYSLOG ((LOG_WARN,
"Can't append failure of UID %lu to %s.",
(unsigned long) uid, ftmp));
return; return;
} }
/* /*
* Output the new failure record and close the log file. * Append the new failure record and close the log file.
*/ */
write (fd, (const char *) failent, sizeof *failent); if ( (write (fd, (const void *) failent, sizeof *failent) != (ssize_t) sizeof *failent)
close (fd); || (close (fd) != 0)) {
/* TODO: check if the file could be closed */ SYSLOG ((LOG_WARN,
"Can't append failure of UID %lu to %s.",
(unsigned long) uid, ftmp));
}
} }