in src/common/commonutils/PassUtils.c [172:282]
int CheckLockoutForFailedPasswordAttempts(const char* fileName, const char* pamSo, char commentCharacter, char** reason, OsConfigLogHandle log)
{
const char* auth = "auth";
const char* required = "required";
FILE* fileHandle = NULL;
char* line = NULL;
char* authValue = NULL;
int deny = INT_ENOENT;
int unlockTime = INT_ENOENT;
long lineMax = sysconf(_SC_LINE_MAX);
int status = ENOENT;
if ((NULL == fileName) || (NULL == pamSo))
{
OsConfigLogError(log, "CheckLockoutForFailedPasswordAttempts: invalid arguments");
return EINVAL;
}
else if (0 != CheckFileExists(fileName, reason, log))
{
// CheckFileExists logs
return ENOENT;
}
else if (NULL == (line = malloc(lineMax + 1)))
{
OsConfigLogError(log, "CheckLockoutForFailedPasswordAttempts: out of memory");
return ENOMEM;
}
else
{
memset(line, 0, lineMax + 1);
}
if (NULL == (fileHandle = fopen(fileName, "r")))
{
OsConfigLogInfo(log, "CheckLockoutForFailedPasswordAttempts: cannot read from '%s' (errno: %d)", fileName, errno);
status = EACCES;
}
else
{
status = ENOENT;
while (NULL != fgets(line, lineMax + 1, fileHandle))
{
// Example of valid lines:
//
// 'auth required pam_tally2.so onerr=fail audit silent deny=5 unlock_time=900'
// 'auth required pam_faillock.so preauth silent audit deny=3 unlock_time=900'
// 'auth required pam_tally.so onerr=fail deny=3 unlock_time=900'
if ((commentCharacter == line[0]) || (EOL == line[0]))
{
status = 0;
continue;
}
else if ((NULL != strstr(line, auth)) && (NULL != strstr(line, pamSo)) &&
(NULL != (authValue = GetStringOptionFromBuffer(line, auth, ' ', log))) && (0 == strcmp(authValue, required)) &&
(0 <= (deny = GetIntegerOptionFromBuffer(line, "deny", '=', log))) && (deny <= 5) &&
(0 < (unlockTime = GetIntegerOptionFromBuffer(line, "unlock_time", '=', log))))
{
OsConfigLogInfo(log, "CheckLockoutForFailedPasswordAttempts: '%s %s %s' found uncommented with 'deny' set to %d and 'unlock_time' set to %d in '%s'",
auth, required, pamSo, deny, unlockTime, fileName);
OsConfigCaptureSuccessReason(reason, "'%s %s %s' found uncommented with 'deny' set to %d and 'unlock_time' set to %d in '%s'",
auth, required, pamSo, deny, unlockTime, fileName);
status = 0;
FREE_MEMORY(authValue);
break;
}
else
{
FREE_MEMORY(authValue);
status = ENOENT;
}
memset(line, 0, lineMax + 1);
}
if (status)
{
if (INT_ENOENT == deny)
{
OsConfigLogInfo(log, "CheckLockoutForFailedPasswordAttempts: 'deny' not found in '%s' for '%s'", fileName, pamSo);
OsConfigCaptureReason(reason, "'deny' not found in '%s' for '%s'", fileName, pamSo);
}
else
{
OsConfigLogInfo(log, "CheckLockoutForFailedPasswordAttempts: 'deny' found set to %d in '%s' for '%s' instead of a value between 0 and 5",
deny, fileName, pamSo);
OsConfigCaptureReason(reason, "'deny' found set to %d in '%s' for '%s' instead of a value between 0 and 5", deny, fileName, pamSo);
}
if (INT_ENOENT == unlockTime)
{
OsConfigLogInfo(log, "CheckLockoutForFailedPasswordAttempts: 'unlock_time' not found in '%s' for '%s'", fileName, pamSo);
OsConfigCaptureReason(reason, "'unlock_time' not found in '%s' for '%s'", fileName, pamSo);
}
else
{
OsConfigLogInfo(log, "CheckLockoutForFailedPasswordAttempts: 'unlock_time' found set to %d in '%s' for '%s' instead of a positive value",
unlockTime, fileName, pamSo);
OsConfigCaptureReason(reason, "'unlock_time' found set to %d in '%s' for '%s' instead of a positive value", unlockTime, fileName, pamSo);
}
}
fclose(fileHandle);
}
FREE_MEMORY(line);
return status;
}