0

I'm new to this Credential Provider stuff. And I decided to start with Microsoft's V2 Credential Provider Sample.

The sample only adds the custom Credential Provider for the local administrator account. But I'd like to have it for every other local account.

I have looked into these questions:

And I also make the following changes to my code in reference to this GitHub repo.

In CSampleProvider.h:

// CSampleCredential                       *_pCredential;   -> From this
std::vector<CSampleCredential*>         _pCredential;       -> To this

In CSampleProvider.cpp:

CSampleProvider::~CSampleProvider()
{
    // if (_pCredential != nullptr)
    // {
    //    _pCredential->Release();
    //    _pCredential = nullptr;
    // }
    _ReleaseEnumerateCredentials();
   ...
}


HRESULT CSampleProvider::GetCredentialCount(...)
{
    ...
    // *pdwCount = 1;
    DWORD dwUserCount;
    _pCredProviderUserArray->GetCount(&dwUserCount);
    *pdwCount = dwUserCount;
    ...
}

HRESULT CSampleProvider::GetCredentialAt(...) {
    ...
    // if ((dwIndex == 0) && ppcpc)
    // {
    //    hr = _pCredential->QueryInterface(IID_PPV_ARGS(ppcpc));
    // }
    if ((dwIndex == 0) && ppcpc)
    {
        hr = _pCredential[dwIndex]->QueryInterface(IID_PPV_ARGS(ppcpc));
    }
    ...
}

void CSampleProvider::_ReleaseEnumeratedCredentials()
{
    DWORD dwUserCount;
    _pCredProviderUserArray->GetCount(&dwUserCount);
    if (!_pCredential.empty())
    {
        for (DWORD i = 0; i < dwUserCount; i++)
        {
            _pCredential[0]->Release();
            _pCredential.erase(_pCredential.begin());
        }
    }
}

HRESULT CSampleProvider::_EnumerateCredentials()
{
    HRESULT hr = E_UNEXPECTED;
    if (_pCredProviderUserArray != nullptr)
    {
        DWORD dwUserCount;
        _pCredProviderUserArray->GetCount(&dwUserCount);
        if (dwUserCount > 0)
        {
            for (DWORD i = 0; i < dwUserCount; i++) {
                ICredentialProviderUser *pCredUser;
                hr = _pCredProviderUserArray->GetAt(0, &pCredUser);
                if (SUCCEEDED(hr))
                {
                    _pCredential.push_back(new(std::nothrow) CSampleCredential());
                    if (_pCredential[i] != nullptr)
                    {
                        hr = _pCredential[i]->Initialize(_cpus, s_rgCredProvFieldDescriptors, s_rgFieldStatePairs, pCredUser);
                        if (FAILED(hr))
                        {
                            _pCredential[i]->Release();
                            _pCredential[i] = nullptr;
                        }
                    }
                    else
                    {
                        hr = E_OUTOFMEMORY;
                    }
                    pCredUser->Release();
                }
            }
        }
    }
    return hr;
}

I saw that I must return different SID in response to getUserSID() but I can't figure out how can I do it properly.

I've crashed some of my environment (fortunately I'm using VMs). And can't really figure out how to do it for multiple local user.

By the way, is there any way to debug the program?

1 Answers1

0

First of all you must absorb the concept of Credential Provider V2. It is significant extend the old concept of Credential Provider

Your CP is supporting the ICredentialProviderSetUserArray interface an supplied with the list of available users. You can use this list to math with your internal storage and check that is it possible to logon into the system using your provider or no.

Based on this information you need to return the number of user's tiles.

Each tile is associated with the user's SID and is displaying next to the user with the same SID.

For debugging the Credential Provider you can use the Credential Invoker.

Alexander
  • 1,232
  • 1
  • 15
  • 24
  • Hi @Alexander, I've looked into the GitHub project you mentioned, and have built it successfully. But I can't figure out how to use the Credential Invoker. – stevenchucp Dec 23 '22 at 03:12
  • You must start debugger using freshly build `CredentialInvoker.exe` as startup program for your credential provider library. – Alexander Dec 23 '22 at 08:41
  • How can I make the invoker to use my credential provider dll? Should I register it first? – stevenchucp Jan 05 '23 at 12:30
  • Yes, of course it must be already registered prior to invocation. – Alexander Jan 06 '23 at 13:12
  • It's assumed that your provider is supporting`CPUS_CREDUI` scenario. – Alexander Jan 06 '23 at 13:19
  • Hi @Alexander, I'm currently developing a CP and I want to debug it. I built and run your SampleCredentialInvoker and the SampleCredUiCredentialProvider, get it running (copied into System32 and updated registry), but I don't understand how i can debug the dll since it is no more in project build directory? Should i modify registry path to build folder? – Lefix Aug 23 '23 at 07:11
  • Hi @Lefix, to debug CP you must set in the Visual Studio Project an SampleCredentialInvoker.exe as a startup application. – Alexander Aug 23 '23 at 07:19
  • That's what i've done, and i can play with SampleCredUiCredentialProvider (and my CP if I implement the CredUI cpus). But i was wondering if you managed to Debug the DLL (with breakpoints etc.)? – Lefix Aug 24 '23 at 07:24
  • I have successfully debugged my CPs using this application (this is it's main goal). – Alexander Aug 24 '23 at 14:23
  • To successfully debug your CP you must register it's DLL file from build directory of your project. There are no restrictions on the location of CP DLL file. – Alexander Aug 24 '23 at 14:25
  • Ok I was confusing the visual studio startup project and tht Dll's project debug startup application (In Properties/Debugging/Command). I registered my CP directly from my solution Build folder and run. Everything launch (and crash because of a bug in my CP) but i can't debug my DLL, when setting a breakpoint, i get "The breakpoint will not currently be hit: No symbols have been loaded for this document". Do you experienced similar issue? If not, i'll create a new thread for this new problem! – Lefix Aug 24 '23 at 16:43
  • I have same issues several times. Try to remove all other traces of your CP from the file system and from the registry. Don't forgot about 32/64 issues of file system and/or registry paths. – Alexander Aug 25 '23 at 08:34
  • Also don’t forget to set working folder to your bild directory. – Alexander Aug 27 '23 at 05:02