I have a custom credential provider that was previously using the eventcreate
process to log messages. However, after making changes to the logging mechanism, the credential provider has stopped working altogether.
Previous Logging Mechanism (Working):
The original logging function looked like this:
template <typename... Args>
static void debug(const char* format, Args... args)
{
std::unique_lock<std::mutex> lock(Log::m_smutex);
if (Log::isLogEnabled())
{
char command[] = "eventcreate.exe /t information /id 1 /l application /d ";
int length = std::snprintf(nullptr, 0, format, args...);
std::unique_ptr<char[]> buf(new char[length + 1]);
std::snprintf(buf.get(), length + 1, format, args...);
length = static_cast<int>(strlen(command) + strlen(buf.get()) + 3);
std::unique_ptr<char[]> proc(new char[length]);
strcpy_s(proc.get(), length, command);
strcat_s(proc.get(), length, """);
strcat_s(proc.get(), length, buf.get());
strcat_s(proc.get(), length, """);
STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
CreateProcessA(NULL, proc.get(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
}
On Windows 11 this credential provider is showing inconsistent behaviour, where a user is sometimes able to log in the Windows and sometimes cannot. The same credential provider works on all Windows Servers and Windows 10 without any problem. So, while debugging I saw that for logs this existing credential provider creates Windows eventcreate
process and uses WaitForSingleObject(pi.hProcess, INFINITE);
to wait for the process result. I thought that maybe there’s privilege issue which might be causing the credential provider to misbehave because it might not be able to create eventcreate
process OR it might be waiting for process to finish indefinitely because of WaitForSingleObject(pi.hProcess, INFINITE);
line in the code.
So to simplify this I just rewrote the logger function as below.
template <typename... Args>
static void debug(const char* format, Args... args)
{
std::unique_lock<std::mutex> lock(Log::m_smutex);
Log::getLogPath();
std::string logFilePath(fullLogPath);
std::ofstream logFileStream(logFilePath, std::ios_base::app);
if (!logFileStream.fail())
{
std::string logMessage = fmt::format(format, args...);
logFileStream << logMessage << std::endl;
logFileStream.flush();
logFileStream.close();
}
else
{
std::cerr << "Failed to open log file: " << logFilePath << std::endl;
}
}
Issue:
Since switching to the new logging mechanism, the credential provider no longer functions at all, whereas previously with old logging mechanism it sometimes worked and sometimes did not.
Questions:
What could be causing the credential provider to stop functioning after changing the logging mechanism?
Any insights or suggestions would be greatly appreciated!