Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I handle password expiry in the credential provider? #3

Open
Mohitkiran opened this issue Nov 24, 2019 · 20 comments
Open

How can I handle password expiry in the credential provider? #3

Mohitkiran opened this issue Nov 24, 2019 · 20 comments

Comments

@Mohitkiran
Copy link

Mohitkiran commented Nov 24, 2019

Hi thanks for this project it helped me alot, can you please help me out how can I handle password expiry in credential provider where the user should be prompted to change password and should be able to change password from my credential provider when his password expired, Thank you.

@DavidWeiss2
Copy link
Owner

@Mohitkiran
Copy link
Author

Thanks for the reply, what changes need to be done in getSerialization while implementing this CPUS_CHANGE_PASSWORD scenario? What method should I call to pass the old password and new password?

@DavidWeiss2
Copy link
Owner

The remarks on this:
https://docs.microsoft.com/en-us/windows/win32/api/credentialprovider/nf-credentialprovider-icredentialprovidercredential-getserialization

I am using the link to the source for maintainability. if it will be changed in the docs the answer will remain the same.

@Mohitkiran
Copy link
Author

Mohitkiran commented Dec 20, 2019

Thanks guys those links should help! Also guys how can I make this credential provider compatible for windows 8 and window 2012 R2 server? What steps are needed to be performed to achieve this? I tried to install in windows 2012 R2 server and I can't see the my credential provider in login screen, I checked the registry values and CLSID of my credential provider is added under HKLM/SOFTWARE/Microsoft/Windows/Current Version/Authentication/Credential Providers and also .Dll is placed in system 32.

@DavidWeiss2
Copy link
Owner

Can you give me more info?

@multiOTP
Copy link

Do you have VCRedist Visual Studio C++ runtimes installed ?

@Mohitkiran
Copy link
Author

Do you have VCRedist Visual Studio C++ runtimes installed ?

Yes I have installed VCRedist 2015 x64 in the Windows R2 2012 server, still I am not able to see my custom CP in sign in options.

@Mohitkiran
Copy link
Author

Can you give me more info?

Hi David, can you tell what info you need so that I can mention that specifically?

@professormahi
Copy link

Do you have VCRedist Visual Studio C++ runtimes installed ?

Yes I have installed VCRedist 2015 x64 in the Windows R2 2012 server, still I am not able to see my custom CP in sign in options.

Same issue! How did you solved that?

@gokulraj381
Copy link

hi, first of all thanks to DavidWeiss2 bcz of his github details about cp that helped me a lot. i am new to credential provider and i am trying to do a change cache credential password (password change).
In CSampleCredential.cpp file in GetSerialization(...) function

case CPUS_CHANGE_PASSWORD:
if(newPassword.Compare(confirmPassword) == 0)
{
KERB_CHANGEPASSWORD_REQUEST kcpr;
ZeroMemory(&kcpr, sizeof(kcpr));

                    hr = UnicodeStringInitWithString(m_domain, &kcpr.DomainName);

                    if (SUCCEEDED(hr))
                    {
                        hr = UnicodeStringInitWithString(m_username, &kcpr.AccountName);

                        if (SUCCEEDED(hr))
                        {
                            hr = UnicodeStringInitWithString(_rgFieldStrings[SFI_PASSWORD], &kcpr.OldPassword);
                            hr = UnicodeStringInitWithString(_rgFieldStrings[SFI_NEWPASSWORD], &kcpr.NewPassword);

                            if (SUCCEEDED(hr))
                            {
                                kcpr.MessageType = KerbChangePasswordMessage;
                                kcpr.Impersonating = FALSE;
                                hr = KerbChangePasswordPack( kcpr, &pcpcs->rgbSerialization, &pcpcs->cbSerialization);

                                if (SUCCEEDED(hr))
                                {
                                    ULONG ulAuthPackage;
                                    hr = RetrieveNegotiateAuthPackage(&ulAuthPackage);
                                    if (SUCCEEDED(hr))
                                    {
                                        pcpcs->ulAuthenticationPackage = ulAuthPackage;
                                        pcpcs->clsidCredentialProvider = CLSID_CSampleProvider;

                                        *pcpgsr = CPGSR_RETURN_CREDENTIAL_FINISHED;
                                    }
                                }
                            }
                        }
                    }
                }
        break;

and In "helpers.cpp" file you have to enter a new function code if this function is not there for password change
//pack the struct of KERB_CHANGEPASSWORD_REQUEST
HRESULT KerbChangePasswordPack(
const KERB_CHANGEPASSWORD_REQUEST& kcpr,
BYTE** prgb,
DWORD* pcb
)
{
HRESULT hr;

DWORD cb = sizeof(kcpr) +
    kcpr.DomainName.Length +
    kcpr.AccountName.Length +
    kcpr.OldPassword.Length +
    kcpr.NewPassword.Length;

KERB_CHANGEPASSWORD_REQUEST* pkcpr = (KERB_CHANGEPASSWORD_REQUEST*)CoTaskMemAlloc(cb);

if (pkcpr)
{
    pkcpr->MessageType = kcpr.MessageType;

    BYTE* pbBuffer = (BYTE*)pkcpr + sizeof(KERB_CHANGEPASSWORD_REQUEST);

    _UnicodeStringPackedUnicodeStringCopy(kcpr.DomainName, (PWSTR)pbBuffer, &pkcpr->DomainName);
    pkcpr->DomainName.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkcpr);
    pbBuffer += pkcpr->DomainName.Length;

    _UnicodeStringPackedUnicodeStringCopy(kcpr.AccountName, (PWSTR)pbBuffer, &pkcpr->AccountName);
    pkcpr->AccountName.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkcpr);
    pbBuffer += pkcpr->AccountName.Length;

    _UnicodeStringPackedUnicodeStringCopy(kcpr.OldPassword, (PWSTR)pbBuffer, &pkcpr->OldPassword);
    pkcpr->OldPassword.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkcpr);
    pbBuffer += pkcpr->OldPassword.Length;

    _UnicodeStringPackedUnicodeStringCopy(kcpr.NewPassword, (PWSTR)pbBuffer, &pkcpr->NewPassword);
    pkcpr->NewPassword.Buffer = (PWSTR)(pbBuffer - (BYTE*)pkcpr);

    *prgb = (BYTE*)pkcpr;
    *pcb = cb;

    hr = S_OK;
}
else
{
    hr = E_OUTOFMEMORY;
}

return hr;

}

now the problem for me is, what are the changing i want to do except from these. like how to change usage scenario to cpus_change_password and how to pass control to get serialization so that to run these code.

like what are the other things i need to do except from these

@Mohitkiran
Copy link
Author

I think you can replicate the password change scenario by changing password expiry policies in active directory for the test user. @gokulraj381

@gokulraj381
Copy link

NO , my problem is when the user is offline (like he is not near domain controller). i want to change his password (as he is not under domain controller) in cache credential of his laptop. to do that is there any API or i need to implement CPUS_CHANGE_PASSWORD

@gokulraj381
Copy link

can i get ur instagram id or gmail id so that i can contact you and ask about my doubt

@Mohitkiran
Copy link
Author

Mohitkiran commented Jul 3, 2020

When you are not able to reach domain controller and you want to change the cached password of domain user that use case is not supported up to my knowledge, mohitkiranmanga@gmail.com.

@gokulraj381
Copy link

but brother the domain password are stored in our laptop as cache credential (to authenticate when the dc is not available). now i just need to change that cache credential password. do u know anybody who knows about co better??

@Mohitkiran
Copy link
Author

@gokulraj381
Copy link

brother that is what i am saying ,the cached copy which he told , that is the thing I want to change !!! for that he told that we need old password and i also have it. the method how to do it is the question

for referal his answer

Locally you just has a cached copy of it, but that's not the master copy of it (which is why you don't see the user listed as a local user on the machine).

In order for them to reset their password they'll need to enter their existing password in any case, so even if you could initiate it locally it wouldn't help without the existing password.

the existing password i have it, i just want the method

@Vincent2019
Copy link

Hello, I am a developer from China. I would like to ask a question about how to make remote login users have the same credentials as those who log in locally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants