Reputation: 7249
The following use of LogonUser
will crash my application.
inline std::string w_to_string(std::wstring wstr) {
typedef std::codecvt_utf8<wchar_t> convert_type;
std::wstring_convert<convert_type, wchar_t> converter;
return converter.to_bytes(wstr);
}
inline const std::wstring to_wstring(const std::string& str) {
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return converter.from_bytes(str);
}
inline bool verify(const std::string username,
const std::string password, const std::string domain) {
auto user = to_wstring(username);
auto pass = to_wstring(password);
auto dom = to_wstring(domain);
PHANDLE hToken;
//UNICODE is set
return LogonUser(user.c_str(), dom.c_str(), pass.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, hToken);
}
However if I replace auto pass = to_wstring(password);
with auto pass = to_wstring("test");
everything works fine.
Can someone explain why this is the case and how to avoid it?
Upvotes: 0
Views: 209
Reputation: 596497
The problem is not with your strings, it is with your hToken
variable. You are passing an uninitialized pointer to LogonUser()
, so it writes the user's token to random memory, which is undefined behavior so anything can happen.
You need to pass a pointer to a valid HANDLE
variable, and then call CloseHandle()
when you are done using it, eg:
inline bool verify(const std::string username, const std::string password, const std::string domain)
{
auto user = to_wstring(username);
auto pass = to_wstring(password);
auto dom = to_wstring(domain);
HANDLE hToken;
bool success = LogonUserW(user.c_str(), dom.c_str(), pass.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken);
if (success)
CloseHandle(hToken);
return success;
}
Which can be simplified to this:
inline bool verify(const std::string username, const std::string password, const std::string domain)
{
HANDLE hToken;
bool success = LogonUserW(to_wstring(username).c_str(), to_wstring(domain).c_str(), to_wstring(password).c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken);
if (success)
CloseHandle(hToken);
return success;
}
Upvotes: 2