Example #1
0
int failcheck (uid_t uid, struct faillog *fl, int failed)
{
	int fd;
	struct faillog fail;

	/*
	 * Suppress the check if the log file isn't there.
	 */

	if ((fd = open (FAILLOG_FILE, O_RDWR)) < 0)
		return 1;

	/*
	 * Get the record from the file and determine if the user has
	 * exceeded the failure limit.  If "max" is zero, any number
	 * of failures are permitted.  Only when "max" is non-zero and
	 * "cnt" is greater than or equal to "max" is the account
	 * considered to be locked.
	 *
	 * If read fails, there is no record for this user yet (the
	 * file is initially zero length and extended by writes), so
	 * no need to reset the count.
	 */

	lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
	if (read (fd, (char *) fl, sizeof *fl) != sizeof *fl) {
		close (fd);
		return 1;
	}

	if (too_many_failures (fl)) {
		close (fd);
		return 0;
	}

	/*
	 * The record is updated if this is not a failure.  The count will
	 * be reset to zero, but the rest of the information will be left
	 * in the record in case someone wants to see where the failed
	 * login originated.
	 */

	if (!failed) {
		fail = *fl;
		fail.fail_cnt = 0;

		lseek (fd, (off_t) sizeof fail * uid, SEEK_SET);
		write (fd, (char *) &fail, sizeof fail);
	}
	close (fd);
	return 1;
}
Example #2
0
int failcheck (uid_t uid, struct faillog *fl, bool failed)
{
	int fd;
	struct faillog fail;
	off_t offset_uid = (off_t) (sizeof *fl) * uid;

	/*
	 * Suppress the check if the log file isn't there.
	 */

	if (access (FAILLOG_FILE, F_OK) != 0) {
		return 1;
	}

	fd = open (FAILLOG_FILE, failed?O_RDONLY:O_RDWR);
	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;
	}

	/*
	 * Get the record from the file and determine if the user has
	 * exceeded the failure limit.  If "max" is zero, any number
	 * of failures are permitted.  Only when "max" is non-zero and
	 * "cnt" is greater than or equal to "max" is the account
	 * considered to be locked.
	 *
	 * If read fails, there is no record for this user yet (the
	 * file is initially zero length and extended by writes), so
	 * no need to reset the count.
	 */

	if (   (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
	    || (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
		(void) close (fd);
		return 1;
	}

	if (too_many_failures (fl)) {
		(void) close (fd);
		return 0;
	}

	/*
	 * The record is updated if this is not a failure.  The count will
	 * be reset to zero, but the rest of the information will be left
	 * in the record in case someone wants to see where the failed
	 * login originated.
	 */

	if (!failed) {
		fail = *fl;
		fail.fail_cnt = 0;

		if (   (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
		    || (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));
			(void) close (fd);
		}
	} else {
		(void) close (fd);
	}

	return 1;
}