Protecting the Automatic Logon Password
The automatic logon password should be protected by using the LsaStorePrivateData function.
The following example shows how to protect the automatic logon password. The example retrieves a handle to the Policy object by calling the LsaOpenPolicy function. For more information about the Policy object and Policy object handles, see Policy object and Opening a Policy Object Handle, respectively. The example then sets the protected password by calling the LsaStorePrivateData function. Note that if the caller passes in NULL for the protected password value, then the code clears the existing protected password. Before exiting, the code closes the handle to the Policy object.
#include <windows.h>
#include <stdio.h>
DWORD UpdateDefaultPassword(WCHAR * pwszSecret)
{
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
LSA_HANDLE LsaPolicyHandle = NULL;
LSA_UNICODE_STRING lusSecretName;
LSA_UNICODE_STRING lusSecretData;
USHORT SecretNameLength;
USHORT SecretDataLength;
NTSTATUS ntsResult = STATUS_SUCCESS;
DWORD dwRetCode = ERROR_SUCCESS;
// Object attributes are reserved, so initialize to zeros.
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
// Get a handle to the Policy object.
ntsResult = LsaOpenPolicy(
NULL, // local machine
&ObjectAttributes,
POLICY_CREATE_SECRET,
&LsaPolicyHandle);
if( STATUS_SUCCESS != ntsResult )
{
// An error occurred. Display it as a win32 error code.
dwRetCode = LsaNtStatusToWinError(ntsResult);
wprintf(L"Failed call to LsaOpenPolicy %lu\n", dwRetCode);
return dwRetCode;
}
// Initialize an LSA_UNICODE_STRING for the name of the
// private data ("DefaultPassword").
SecretNameLength = (USHORT)wcslen(L"DefaultPassword");
lusSecretName.Buffer = L"DefaultPassword";
lusSecretName.Length = SecretNameLength * sizeof(WCHAR);
lusSecretName.MaximumLength =
(SecretNameLength+1) * sizeof(WCHAR);
// If the pwszSecret parameter is NULL, then clear the secret.
if( NULL == pwszSecret )
{
wprintf(L"Clearing the secret...\n");
ntsResult = LsaStorePrivateData(
LsaPolicyHandle,
&lusSecretName,
NULL);
dwRetCode = LsaNtStatusToWinError(ntsResult);
}
else
{
wprintf(L"Setting the secret...\n");
// Initialize an LSA_UNICODE_STRING for the value
// of the private data.
SecretDataLength = (USHORT)wcslen(pwszSecret);
lusSecretData.Buffer = pwszSecret;
lusSecretData.Length = SecretDataLength * sizeof(WCHAR);
lusSecretData.MaximumLength =
(SecretDataLength+1) * sizeof(WCHAR);
ntsResult = LsaStorePrivateData(
LsaPolicyHandle,
&lusSecretName,
&lusSecretData);
dwRetCode = LsaNtStatusToWinError(ntsResult);
}
LsaClose(LsaPolicyHandle);
if (dwRetCode != ERROR_SUCCESS)
wprintf(L"Failed call to LsaStorePrivateData %lu\n",
dwRetCode);
return dwRetCode;
}
Note that if Winlogon cannot find a password stored by the LsaStorePrivateData function, it will use the DefaultPassword value of the Winlogon key (if it exists) for the automatic logon password.
For more information about automatic logon and the Winlogon registry key, see MSGina.dll Features.
For more information about protecting passwords, see Handling Passwords.
Send comments about this topic to Microsoft
Build date: 3/13/2012
The Community Content section of an MSDN library topic provides an area where developers can collaborate on additional information related to that topic. Use this section to contribute code examples, tips and tricks, and links to other relevant content.
You can use the MSDN Forums (http://forums.microsoft.com/msdn/) or the Microsoft public security newsgroups (http://www.microsoft.com/technet/community/newsgroups/security/) to ask questions or participate in discussions about the APIs.
To submit feedback on the documentation, use the feedback link on this page (see the "Send comments about this topic to Microsoft" link).
If you receive useful information from the forums that you want to share with other developers, we welcome you to post the information here in the community content.
Thank you.
- 8/5/2010
- Jo Lines - MSFT