You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
313 lines
9.0 KiB
313 lines
9.0 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1996.
|
|
//
|
|
// File: cisecret.cxx
|
|
//
|
|
// Functions: CiGetPassword, GetSecret SetSecret
|
|
//
|
|
// History: 10-18-96 dlee Created, mostly from w3svc sources
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <pch.cxx>
|
|
#pragma hdrstop
|
|
|
|
extern "C"
|
|
{
|
|
#include <ntsam.h>
|
|
#include <ntlsa.h>
|
|
}
|
|
|
|
#include <cisecret.hxx>
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: CiGetPassword
|
|
//
|
|
// Synopsis: Looks up a password from the lsa database
|
|
//
|
|
// Arguments: [pcsCatalogName] - friendly name of the catalog
|
|
// [pwcUserName] - domain\user
|
|
// [pwcPassword] - returns the password
|
|
//
|
|
// Returns: TRUE if a password was found, FALSE otherwise
|
|
//
|
|
// History: 29-Oct-96 dlee created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
BOOL CiGetPassword(
|
|
WCHAR const * pwcCatalog,
|
|
WCHAR const * pwcUsername,
|
|
WCHAR * pwcPassword )
|
|
{
|
|
Win4Assert( 0 != pwcCatalog );
|
|
Win4Assert( 0 != pwcUsername );
|
|
|
|
// look for a match of catalog name and domain\user
|
|
|
|
CCiSecretRead secret;
|
|
CCiSecretItem * pItem = secret.NextItem();
|
|
|
|
while ( 0 != pItem )
|
|
{
|
|
if ( ( !_wcsicmp( pwcCatalog, pItem->getCatalog() ) ) &&
|
|
( !_wcsicmp( pwcUsername, pItem->getUser() ) ) )
|
|
{
|
|
wcscpy( pwcPassword, pItem->getPassword() );
|
|
return TRUE;
|
|
}
|
|
|
|
pItem = secret.NextItem();
|
|
}
|
|
|
|
return FALSE;
|
|
} //CiGetPassword
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: SetSecret
|
|
//
|
|
// Synopsis: Creates or resets a secret value
|
|
//
|
|
// Arguments: [Server] - Server secret lives on, 0 for local machine
|
|
// [SecretName] - name of the secret
|
|
// [pSecret] - secret to set
|
|
// [cbSecret] - # of bytes in pSecret
|
|
//
|
|
// History: 18-Oct-96 dlee copied from w3svc code and ci-ized
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
void SetSecret(
|
|
WCHAR const * Server,
|
|
WCHAR const * SecretName,
|
|
WCHAR const * pSecret,
|
|
DWORD cbSecret )
|
|
{
|
|
UNICODE_STRING unicodeServer;
|
|
RtlInitUnicodeString( &unicodeServer,
|
|
Server );
|
|
|
|
//
|
|
// Initialize the unicode string by hand so we can handle '\0' in the
|
|
// string
|
|
//
|
|
|
|
UNICODE_STRING unicodePassword;
|
|
unicodePassword.Buffer = (WCHAR *) pSecret;
|
|
unicodePassword.Length = (USHORT) cbSecret;
|
|
unicodePassword.MaximumLength = (USHORT) cbSecret;
|
|
|
|
//
|
|
// Open a policy to the remote LSA
|
|
//
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
NULL,
|
|
0L,
|
|
NULL,
|
|
NULL );
|
|
|
|
LSA_HANDLE hPolicy;
|
|
NTSTATUS ntStatus = LsaOpenPolicy( &unicodeServer,
|
|
&ObjectAttributes,
|
|
POLICY_ALL_ACCESS,
|
|
&hPolicy );
|
|
|
|
if ( !NT_SUCCESS( ntStatus ) )
|
|
THROW( CException( ntStatus ) );
|
|
|
|
//
|
|
// Create or open the LSA secret
|
|
//
|
|
|
|
UNICODE_STRING unicodeSecret;
|
|
RtlInitUnicodeString( &unicodeSecret,
|
|
SecretName );
|
|
|
|
LSA_HANDLE hSecret;
|
|
ntStatus = LsaCreateSecret( hPolicy,
|
|
&unicodeSecret,
|
|
SECRET_ALL_ACCESS,
|
|
&hSecret );
|
|
|
|
if ( !NT_SUCCESS( ntStatus ) )
|
|
{
|
|
// If the secret already exists, then we just need to open it
|
|
|
|
if ( STATUS_OBJECT_NAME_COLLISION == ntStatus )
|
|
ntStatus = LsaOpenSecret( hPolicy,
|
|
&unicodeSecret,
|
|
SECRET_ALL_ACCESS,
|
|
&hSecret );
|
|
|
|
if ( !NT_SUCCESS( ntStatus ) )
|
|
{
|
|
LsaClose( hPolicy );
|
|
THROW( CException( ntStatus ) );
|
|
}
|
|
}
|
|
|
|
//
|
|
// Set the secret value
|
|
//
|
|
|
|
ntStatus = LsaSetSecret( hSecret,
|
|
&unicodePassword,
|
|
&unicodePassword );
|
|
|
|
LsaClose( hSecret );
|
|
LsaClose( hPolicy );
|
|
|
|
if ( !NT_SUCCESS( ntStatus ) )
|
|
THROW( CException( ntStatus ) );
|
|
} //SetSecret
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: GetSecret
|
|
//
|
|
// Synopsis: Retrieves a secret value
|
|
//
|
|
// Arguments: [Server] - Server secret lives on, 0 for local machine
|
|
// [SecretName] - name of the secret
|
|
// [ppSecret] - returns the secret value that must be deleted
|
|
// with LocalFree
|
|
// [pcbSecret] - Returns the count of bytes in the secret
|
|
//
|
|
// Returns: TRUE if secret was found, FALSE if secret didn't exist
|
|
// throws on all other errors.
|
|
//
|
|
// History: 18-Oct-96 dlee added header and and ci-ized
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
// These defines are used in the GetSecret function call.
|
|
|
|
WCHAR g_wchUnicodeNull[] = L"";
|
|
|
|
#define _InitUnicodeString( pUnicode, pwch ) \
|
|
{ \
|
|
(pUnicode)->Buffer = pwch; \
|
|
(pUnicode)->Length = wcslen( pwch ) * sizeof(WCHAR); \
|
|
(pUnicode)->MaximumLength = (pUnicode)->Length + sizeof(WCHAR); \
|
|
}
|
|
|
|
#define InitUnicodeString( pUnicode, pwch) \
|
|
if (pwch == NULL) { _InitUnicodeString( pUnicode, g_wchUnicodeNull); } \
|
|
else { _InitUnicodeString( pUnicode, pwch); } \
|
|
|
|
|
|
BOOL GetSecret(
|
|
WCHAR const * Server,
|
|
WCHAR const * SecretName,
|
|
WCHAR ** ppSecret,
|
|
ULONG * pcbSecret )
|
|
{
|
|
|
|
Win4Assert ( 0 != ppSecret );
|
|
Win4Assert ( 0 != SecretName );
|
|
|
|
UNICODE_STRING unicodeServer;
|
|
InitUnicodeString( &unicodeServer,
|
|
(WCHAR *) Server );
|
|
|
|
//
|
|
// Open a policy to the remote LSA
|
|
//
|
|
|
|
Win4Assert ( 0 != ppSecret );
|
|
Win4Assert ( 0 != SecretName );
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
NULL,
|
|
0L,
|
|
NULL,
|
|
NULL );
|
|
|
|
Win4Assert ( 0 != ppSecret );
|
|
Win4Assert ( 0 != SecretName );
|
|
|
|
LSA_HANDLE hPolicy;
|
|
NTSTATUS ntStatus = LsaOpenPolicy( &unicodeServer,
|
|
&ObjectAttributes,
|
|
POLICY_ALL_ACCESS,
|
|
&hPolicy );
|
|
|
|
Win4Assert ( 0 != ppSecret );
|
|
Win4Assert ( 0 != SecretName );
|
|
|
|
if ( !NT_SUCCESS( ntStatus ) )
|
|
THROW( CException( LsaNtStatusToWinError( ntStatus ) ) );
|
|
|
|
UNICODE_STRING unicodeSecret;
|
|
InitUnicodeString( &unicodeSecret,
|
|
(WCHAR *) SecretName );
|
|
|
|
//
|
|
// Query the secret value
|
|
//
|
|
|
|
Win4Assert ( 0 != ppSecret );
|
|
Win4Assert ( 0 != SecretName );
|
|
|
|
UNICODE_STRING * punicodePassword;
|
|
ntStatus = LsaRetrievePrivateData( hPolicy,
|
|
&unicodeSecret,
|
|
&punicodePassword );
|
|
|
|
LsaClose( hPolicy );
|
|
|
|
// Don't throw if the secret didn't exist -- just return FALSE
|
|
|
|
if ( STATUS_OBJECT_NAME_NOT_FOUND == ntStatus )
|
|
return FALSE;
|
|
|
|
if ( STATUS_LOCAL_USER_SESSION_KEY == ntStatus )
|
|
return FALSE;
|
|
|
|
if ( !NT_SUCCESS( ntStatus ))
|
|
THROW( CException( ntStatus ) );
|
|
|
|
|
|
Win4Assert ( 0 != ppSecret );
|
|
Win4Assert ( 0 != SecretName );
|
|
|
|
ULONG cbSecret = punicodePassword->Length + sizeof WCHAR;
|
|
|
|
*ppSecret = (WCHAR *) LocalAlloc( LPTR, cbSecret );
|
|
|
|
if ( 0 == *ppSecret )
|
|
{
|
|
RtlZeroMemory( punicodePassword->Buffer,
|
|
punicodePassword->MaximumLength );
|
|
|
|
LsaFreeMemory( (PVOID) punicodePassword );
|
|
THROW( CException( E_OUTOFMEMORY ) );
|
|
}
|
|
|
|
*pcbSecret = cbSecret;
|
|
|
|
//
|
|
// Copy it into the buffer, Length is count of bytes
|
|
//
|
|
|
|
RtlCopyMemory( *ppSecret,
|
|
punicodePassword->Buffer,
|
|
punicodePassword->Length );
|
|
|
|
(*ppSecret)[punicodePassword->Length/sizeof(WCHAR)] = L'\0';
|
|
|
|
RtlZeroMemory( punicodePassword->Buffer,
|
|
punicodePassword->MaximumLength );
|
|
|
|
LsaFreeMemory( (PVOID) punicodePassword );
|
|
|
|
return TRUE;
|
|
} //GetSecret
|
|
|