Skip to content

Instantly share code, notes, and snippets.

@nzbart
Last active February 26, 2021 03:27
Show Gist options
  • Save nzbart/9400412 to your computer and use it in GitHub Desktop.
Save nzbart/9400412 to your computer and use it in GitHub Desktop.
Read / write credentials through CredRead and CredWrite, with a profile load for good measure. Fails under PowerShell remoting.
#include <SDKDDKVer.h>
#include <tchar.h>
#include <Windows.h>
#include <WinCred.h>
#include <Userenv.h>
#include <atlsecurity.h>
#include <Lmcons.h>
#include <iostream>
using namespace std;
template <typename T>
void CheckResult(T success, wchar_t const * const taskName)
{
if (success)
return;
wcout << L"Failed to " << taskName << L": " << GetLastError();
throw wstring(L"Failed to ") + taskName;
}
int wmain()
{
wcout << L"Started." << endl;
wchar_t userName[UNLEN + 1];
DWORD bufferLength = sizeof(userName) / sizeof(userName[0]);
CheckResult(GetUserName(userName, &bufferLength), L"get user name");
wcout << L"User name = " << userName << endl;
HANDLE hToken;
CheckResult(OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken), L"get thread token");
wcout << L"Opened process token." << endl;
PROFILEINFO profile = {};
profile.dwSize = sizeof(profile);
profile.lpUserName = userName;
CheckResult(LoadUserProfile(hToken, &profile), L"load profile");
wcout << L"Loaded user profile." << endl;
wchar_t const target[] = L"TestCredentials";
wchar_t const password[] = L"Password";
CREDENTIALW credsToAdd = {};
credsToAdd.Flags = 0;
credsToAdd.Type = CRED_TYPE_GENERIC;
credsToAdd.TargetName = const_cast<wchar_t*>(target);
credsToAdd.CredentialBlob = (LPBYTE)&password;
credsToAdd.CredentialBlobSize = sizeof(password);
credsToAdd.Persist = CRED_PERSIST_LOCAL_MACHINE;
CheckResult(CredWrite(&credsToAdd, 0), L"write credential");
wcout << L"Wrote successfully." << endl;
PCREDENTIALW creds;
CheckResult(CredRead(target, 1, 0, &creds), L"read credential");
wcout << L"Read successfully." << endl;
wchar_t const * const passwordOut = (wchar_t const * const)creds->CredentialBlob;
wcout << password << endl;
wcout << passwordOut << endl;
wcout << (wstring(password) == wstring(passwordOut) ? L"Success" : L"FAILURE") << endl;
return 0;
}
@mfekry
Copy link

mfekry commented Aug 30, 2016

how it work can you elaborate & if i need to use script to pass current user credential for Exchange server to not prompt for password when configure outlook profile for 1st time is this possible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment