// this file provides a wrapper api to get to the NT specific LSA routines #include "stdafx.h" #include "KMLsa.h" //============================================================= //------------------------------------------------------------- // pass in a NULL pszwServer name to open the local machine HANDLE HOpenLSAPolicy( WCHAR *pszwServer, DWORD *pErr ) { NTSTATUS ntStatus; LSA_OBJECT_ATTRIBUTES objectAttributs; LSA_HANDLE hPolicy; LSA_UNICODE_STRING unicodeServer; // prepare the object attributes InitializeObjectAttributes( &objectAttributs, NULL, 0L, NULL, NULL ); // prepare the lsa_unicode name of the server if ( pszwServer ) { unicodeServer.Buffer = pszwServer; unicodeServer.Length = wcslen(pszwServer) * sizeof(WCHAR); unicodeServer.MaximumLength = unicodeServer.Length + sizeof(WCHAR); } // attempt to open the policy ntStatus = LsaOpenPolicy( pszwServer ? &unicodeServer : NULL, &objectAttributs, POLICY_ALL_ACCESS, &hPolicy ); // check for an error if ( !NT_SUCCESS(ntStatus) ) { *pErr = LsaNtStatusToWinError( ntStatus ); return NULL; } // success, so return the policy handle as a regular handle *pErr = 0; return hPolicy; } //------------------------------------------------------------- BOOL FCloseLSAPolicy( HANDLE hPolicy, DWORD *pErr ) { NTSTATUS ntStatus; // close the policy ntStatus = LsaClose( hPolicy ); // check for an error if ( !NT_SUCCESS(ntStatus) ) { *pErr = LsaNtStatusToWinError( ntStatus ); return FALSE; } // success, so return the policy handle as a regular handle *pErr = 0; return TRUE; } //------------------------------------------------------------- // passing NULL in for pvData deletes the secret BOOL FStoreLSASecret( HANDLE hPolicy, WCHAR* pszwSecretName, void* pvData, WORD cbData, DWORD *pErr ) { LSA_UNICODE_STRING unicodeSecretName; LSA_UNICODE_STRING unicodeData; NTSTATUS ntStatus; // make sure we have a policy and a secret name if ( !hPolicy || !pszwSecretName ) { *pErr = 1; return FALSE; } // prepare the lsa_unicode name of the server unicodeSecretName.Buffer = pszwSecretName; unicodeSecretName.Length = wcslen(pszwSecretName) * sizeof(WCHAR); unicodeSecretName.MaximumLength = unicodeSecretName.Length + sizeof(WCHAR); // prepare the unicode data record if ( pvData ) { unicodeData.Buffer = (WCHAR*)pvData; unicodeData.Length = cbData; unicodeData.MaximumLength = cbData; } // it is now time to store the secret ntStatus = LsaStorePrivateData( hPolicy, &unicodeSecretName, pvData ? &unicodeData : NULL ); // check for an error if ( !NT_SUCCESS(ntStatus) ) { *pErr = LsaNtStatusToWinError( ntStatus ); return FALSE; } // success, so return the policy handle as a regular handle *pErr = 0; return TRUE; } //------------------------------------------------------------- // passing NULL in for pvData deletes the secret PLSA_UNICODE_STRING FRetrieveLSASecret( HANDLE hPolicy, WCHAR* pszwSecretName, DWORD *pErr ) { LSA_UNICODE_STRING unicodeSecretName; LSA_UNICODE_STRING* pUnicodeData = NULL; NTSTATUS ntStatus; // make sure we have a policy and a secret name if ( !hPolicy || !pszwSecretName ) { *pErr = 1; return FALSE; } // prepare the lsa_unicode name of the server unicodeSecretName.Buffer = pszwSecretName; unicodeSecretName.Length = wcslen(pszwSecretName) * sizeof(WCHAR); unicodeSecretName.MaximumLength = unicodeSecretName.Length + sizeof(WCHAR); // it is now time to store the secret ntStatus = LsaRetrievePrivateData( hPolicy, &unicodeSecretName, &pUnicodeData ); // check for an error if ( !NT_SUCCESS(ntStatus) ) { *pErr = LsaNtStatusToWinError( ntStatus ); return NULL; } // success, so return the policy handle as a regular handle *pErr = 0; return (PLSA_UNICODE_STRING)pUnicodeData; }