////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2000-2002 Microsoft Corporation // // Module Name: // CClusCfgCredentials.cpp // // Header File: // CClusCfgCredentials.h // // Description: // This file contains the definition of the CClusCfgCredentials // class. // // The class CClusCfgCredentials is the representation of // account credentials. It implements the IClusCfgCredentials interface. // // Maintained By: // Galen Barbee (GalenB) 17-May-2000 // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // Include Files ////////////////////////////////////////////////////////////////////////////// #include "pch.h" #include "EncryptedBSTR.h" #include "CClusCfgCredentials.h" ////////////////////////////////////////////////////////////////////////////// // Constant Definitions ////////////////////////////////////////////////////////////////////////////// DEFINE_THISCLASS( "CClusCfgCredentials" ); //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CClusCfgCredentials class ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::S_HrCreateInstance // // Description: // Create a CClusCfgCredentials instance. // // Arguments: // ppunkOut // // Return Values: // Pointer to CClusCfgCredentials instance. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CClusCfgCredentials::S_HrCreateInstance( IUnknown ** ppunkOut ) { TraceFunc( "" ); HRESULT hr = S_OK; CClusCfgCredentials * pccc = NULL; if ( ppunkOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // if: pccc = new CClusCfgCredentials(); if ( pccc == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: error allocating object hr = THR( pccc->HrInit() ); if ( FAILED( hr ) ) { goto Cleanup; } // if: HrInit() failed hr = THR( pccc->TypeSafeQI( IUnknown, ppunkOut ) ); Cleanup: if ( FAILED( hr ) ) { LogMsg( L"Server: CClusCfgCredentials::S_HrCreateInstance() failed. (hr = %#08x)", hr ); } // if: if ( pccc != NULL ) { pccc->Release(); } // if: HRETURN( hr ); } //*** CClusCfgCredentials::S_HrCreateInstance ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::CClusCfgCredentials // // Description: // Constructor of the CClusCfgCredentials class. This initializes // the m_cRef variable to 1 instead of 0 to account of possible // QueryInterface failure in DllGetClassObject. // // Arguments: // None. // // Return Value: // None. // //-- ////////////////////////////////////////////////////////////////////////////// CClusCfgCredentials::CClusCfgCredentials( void ) : m_cRef( 1 ) , m_lcid( LOCALE_NEUTRAL ) , m_bstrAccountName( NULL ) , m_bstrAccountDomain( NULL ) { TraceFunc( "" ); // Increment the count of components in memory so the DLL hosting this // object cannot be unloaded. InterlockedIncrement( &g_cObjects ); Assert( m_picccCallback == NULL ); TraceFuncExit(); } //*** CClusCfgCredentials::CClusCfgCredentials ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::~CClusCfgCredentials // // Description: // Desstructor of the CClusCfgCredentials class. // // Arguments: // None. // // Return Value: // None. // //-- ////////////////////////////////////////////////////////////////////////////// CClusCfgCredentials::~CClusCfgCredentials( void ) { TraceFunc( "" ); // There's going to be one less component in memory. Decrement component count. InterlockedDecrement( &g_cObjects ); if ( m_picccCallback != NULL ) { m_picccCallback->Release(); } // if: TraceSysFreeString( m_bstrAccountName ); TraceSysFreeString( m_bstrAccountDomain ); TraceFuncExit(); } //*** CClusCfgCredentials::~CClusCfgCredentials //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CClusterConfiguration -- IUknkown interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::AddRef // // Description: // Increment the reference count of this object by one. // // Arguments: // None. // // Return Value: // The new reference count. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CClusCfgCredentials::AddRef( void ) { TraceFunc( "[IUnknown]" ); InterlockedIncrement( & m_cRef ); CRETURN( m_cRef ); } //*** CClusCfgCredentials::AddRef ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::Release // // Description: // Decrement the reference count of this object by one. // // Arguments: // None. // // Return Value: // The new reference count. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CClusCfgCredentials::Release( void ) { TraceFunc( "[IUnknown]" ); LONG cRef; cRef = InterlockedDecrement( &m_cRef ); if ( cRef == 0 ) { TraceDo( delete this ); } // if: reference count equal to zero CRETURN( cRef ); } //*** CClusCfgCredentials::Release ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::QueryInterface // // Description: // Query this object for the passed in interface. // // Arguments: // riidIn // Id of interface requested. // // ppvOut // Pointer to the requested interface. // // Return Value: // S_OK // If the interface is available on this object. // // E_NOINTERFACE // If the interface is not available. // // E_POINTER // ppvOut was NULL. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CClusCfgCredentials::QueryInterface( REFIID riidIn , void ** ppvOut ) { TraceQIFunc( riidIn, ppvOut ); HRESULT hr = S_OK; // // Validate arguments. // Assert( ppvOut != NULL ); if ( ppvOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } // // Handle known interfaces. // if ( IsEqualIID( riidIn, IID_IUnknown ) ) { *ppvOut = static_cast< IClusCfgCredentials * >( this ); } // if: IUnknown else if ( IsEqualIID( riidIn, IID_IClusCfgCredentials ) ) { *ppvOut = TraceInterface( __THISCLASS__, IClusCfgCredentials, this, 0 ); } // else if: IID_IClusCfgCredentials else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) ) { *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 ); } // else if: IClusCfgInitialize else if ( IsEqualIID( riidIn, IID_IClusCfgSetCredentials ) ) { *ppvOut = TraceInterface( __THISCLASS__, IClusCfgSetCredentials, this, 0 ); } // else if: IClusCfgSetCredentials else { *ppvOut = NULL; hr = E_NOINTERFACE; } // // Add a reference to the interface if successful. // if ( SUCCEEDED( hr ) ) { ((IUnknown *) *ppvOut)->AddRef(); } // if: success Cleanup: QIRETURN_IGNORESTDMARSHALLING1( hr, riidIn, IID_IClusCfgWbemServices ); } //*** CClusCfgCredentials::QueryInterface //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CClusCfgCredentials -- IClusCfgInitialze interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::Initialize // // Description: // Initialize this component. // // Arguments: // punkCallbackIn // lcidIn // // Return Value: // S_OK // Success // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CClusCfgCredentials::Initialize( IUnknown * punkCallbackIn , LCID lcidIn ) { TraceFunc( "[IClusCfgInitialize]" ); HRESULT hr = S_OK; m_lcid = lcidIn; Assert( m_picccCallback == NULL ); if ( punkCallbackIn != NULL ) { hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) ); } // if: HRETURN( hr ); } //*** CClusCfgCredentials::Initialize //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CClusCfgCredentials -- IClusCfgCredentials interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::GetCredentials // // Description: // // Arguments: // pbstrNameOut // pbstrDomainOut // pbstrPasswordOut // // Return Value: // S_OK - Success. // E_OUTOFMEMORY - Error allocating memory. // Other HRESULTs. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CClusCfgCredentials::GetCredentials( BSTR * pbstrNameOut , BSTR * pbstrDomainOut , BSTR * pbstrPasswordOut ) { TraceFunc( "[IClusCfgCredentials]" ); HRESULT hr = S_OK; BSTR bstrName = NULL; BSTR bstrDomain = NULL; BSTR bstrPassword = NULL; // The marshaller doesn't allow null out-parameters, but just to be explicit... if ( pbstrNameOut != NULL ) { *pbstrNameOut = NULL; } if ( pbstrDomainOut != NULL ) { *pbstrDomainOut = NULL; } if ( pbstrPasswordOut != NULL ) { *pbstrPasswordOut = NULL; } if ( ( pbstrNameOut == NULL ) || ( pbstrDomainOut == NULL ) || ( pbstrPasswordOut == NULL ) ) { hr = THR( E_POINTER ); goto Cleanup; } if ( m_bstrAccountName != NULL ) { bstrName = SysAllocString( m_bstrAccountName ); if ( bstrName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } } if ( m_bstrAccountDomain != NULL ) { bstrDomain = SysAllocString( m_bstrAccountDomain ); if ( bstrDomain == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } } hr = STHR( m_encbstrPassword.HrGetBSTR( &bstrPassword ) ); if ( FAILED( hr ) ) { goto Cleanup; } *pbstrNameOut = bstrName; bstrName = NULL; *pbstrDomainOut = bstrDomain; bstrDomain = NULL; *pbstrPasswordOut = bstrPassword; TraceMemoryDelete( bstrPassword, false ); bstrPassword = NULL; hr = S_OK; // because decrypting might have returned S_FALSE Cleanup: SysFreeString( bstrName ); SysFreeString( bstrDomain ); if ( bstrPassword != NULL ) { CEncryptedBSTR::SecureZeroBSTR( bstrPassword ); TraceSysFreeString( bstrPassword ); } HRETURN( hr ); } //*** CClusCfgCredentials::GetCredentials ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::GetIdentity // // Description: // // Arguments: // pbstrNameOut // pbstrDomainOut // // Return Value: // S_OK - Success. // E_OUTOFMEMORY - Error allocating memory. // Other HRESULTs. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CClusCfgCredentials::GetIdentity( BSTR * pbstrNameOut , BSTR * pbstrDomainOut ) { TraceFunc( "[IClusCfgCredentials]" ); HRESULT hr = S_OK; BSTR bstrName = NULL; BSTR bstrDomain = NULL; // The marshaller doesn't allow null out-parameters, but just to be explicit... if ( pbstrNameOut != NULL ) { *pbstrNameOut = NULL; } if ( pbstrDomainOut != NULL ) { *pbstrDomainOut = NULL; } if ( ( pbstrNameOut == NULL ) || ( pbstrDomainOut == NULL ) ) { hr = THR( E_POINTER ); goto Cleanup; } if ( m_bstrAccountName != NULL ) { bstrName = SysAllocString( m_bstrAccountName ); if ( bstrName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } } if ( m_bstrAccountDomain != NULL ) { bstrDomain = SysAllocString( m_bstrAccountDomain ); if ( bstrDomain == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } } *pbstrNameOut = bstrName; bstrName = NULL; *pbstrDomainOut = bstrDomain; bstrDomain = NULL; Cleanup: SysFreeString( bstrName ); SysFreeString( bstrDomain ); HRETURN( hr ); } //*** CClusCfgCredentials::GetCredentials ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::GetPassword // // Description: // // Arguments: // pbstrPasswordOut // // Return Value: // S_OK - Success. // E_OUTOFMEMORY - Error allocating memory. // Other HRESULTs. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CClusCfgCredentials::GetPassword( BSTR * pbstrPasswordOut ) { TraceFunc( "[IClusCfgCredentials]" ); HRESULT hr = S_OK; BSTR bstrPassword = NULL; // The marshaller doesn't allow null out-parameters, but just to be explicit... if ( pbstrPasswordOut == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } *pbstrPasswordOut = NULL; hr = STHR( m_encbstrPassword.HrGetBSTR( &bstrPassword ) ); if ( FAILED( hr ) ) { goto Cleanup; } *pbstrPasswordOut = bstrPassword; TraceMemoryDelete( bstrPassword, false ); bstrPassword = NULL; hr = S_OK; // because decrypting might have returned S_FALSE Cleanup: if ( bstrPassword != NULL ) { CEncryptedBSTR::SecureZeroBSTR( bstrPassword ); TraceSysFreeString( bstrPassword ); } HRETURN( hr ); } //*** CClusCfgCredentials::GetPassword ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::SetCredentials // // Description: // // Arguments: // pcszNameIn // pcszDomainIn // pcszPasswordIn // // Return Value: // S_OK - Success. // E_OUTOFMEMORY - Error allocating memory. // Other HRESULTs. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CClusCfgCredentials::SetCredentials( LPCWSTR pcszNameIn, LPCWSTR pcszDomainIn, LPCWSTR pcszPasswordIn ) { TraceFunc( "[IClusCfgCredentials]" ); HRESULT hr = S_OK; BSTR bstrNewName = NULL; BSTR bstrNewDomain = NULL; if ( pcszNameIn != NULL ) { bstrNewName = TraceSysAllocString( pcszNameIn ); if ( bstrNewName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: } // if: if ( pcszDomainIn != NULL ) { bstrNewDomain = TraceSysAllocString( pcszDomainIn ); if ( bstrNewDomain == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: } // if: // Keep this after name and domain, to preserve password in case copying either of the others fails. if ( pcszPasswordIn != NULL ) { size_t cchPassword = wcslen( pcszPasswordIn ); hr = THR( m_encbstrPassword.HrSetWSTR( pcszPasswordIn, cchPassword ) ); if ( FAILED( hr ) ) { goto Cleanup; } } // if: if ( bstrNewName != NULL ) { TraceSysFreeString( m_bstrAccountName ); m_bstrAccountName = bstrNewName; bstrNewName = NULL; } // if: if ( bstrNewDomain != NULL ) { TraceSysFreeString( m_bstrAccountDomain ); m_bstrAccountDomain = bstrNewDomain; bstrNewDomain = NULL; } // if: Cleanup: TraceSysFreeString( bstrNewName ); TraceSysFreeString( bstrNewDomain ); HRETURN( hr ); } //*** CClusCfgCredentials::SetCredentials ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::AssignTo // // Description: // // Arguments: // picccDestIn // // Return Value: // S_OK - Success. // E_OUTOFMEMORY - Error allocating memory. // Other HRESULTs. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CClusCfgCredentials::AssignTo( IClusCfgCredentials * picccDestIn ) { TraceFunc( "[IClusCfgCredentials]" ); HRESULT hr = S_OK; BSTR bstrPassword = NULL; if ( picccDestIn == NULL ) { hr = THR( E_POINTER ); goto Cleanup; } hr = THR( m_encbstrPassword.HrGetBSTR( &bstrPassword ) ); if ( FAILED( hr ) ) { goto Cleanup; } hr = THR( picccDestIn->SetCredentials( m_bstrAccountName, m_bstrAccountDomain, bstrPassword ) ); if ( FAILED( hr ) ) { goto Cleanup; } Cleanup: if ( bstrPassword != NULL ) { CEncryptedBSTR::SecureZeroBSTR( bstrPassword ); TraceSysFreeString( bstrPassword ); } HRETURN( hr ); } //*** CClusCfgCredentials::AssignTo ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::AssignFrom // // Description: // // Arguments: // picccSourceIn // // Return Value: // S_OK - Success. // E_OUTOFMEMORY - Error allocating memory. // Other HRESULTs. // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CClusCfgCredentials::AssignFrom( IClusCfgCredentials * picccSourceIn ) { TraceFunc( "[IClusCfgCredentials]" ); HRESULT hr = S_OK; BSTR bstrName = NULL; BSTR bstrDomain = NULL; BSTR bstrPassword = NULL; hr = THR( picccSourceIn->GetCredentials( &bstrName, &bstrDomain, &bstrPassword ) ); if ( FAILED( hr ) ) { goto Cleanup; } hr = THR( m_encbstrPassword.HrSetBSTR( bstrPassword ) ); if ( FAILED( hr ) ) { goto Cleanup; } m_bstrAccountName = bstrName; TraceMemoryAddBSTR( m_bstrAccountName ); bstrName = NULL; m_bstrAccountDomain = bstrDomain; TraceMemoryAddBSTR( m_bstrAccountDomain ); bstrDomain = NULL; Cleanup: SysFreeString( bstrName ); SysFreeString( bstrDomain ); if ( bstrPassword != NULL ) { CEncryptedBSTR::SecureZeroBSTR( bstrPassword ); TraceSysFreeString( bstrPassword ); } HRETURN( hr ); } //*** CClusCfgCredentials::AssignFrom //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CClusCfgCredentials -- IClusCfgSetCredentials interface. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::SetDomainCredentials // // Description: // // Arguments: // pcszCredentialsIn // // Return Value: // S_OK - Success. // E_INVALIDARG - Required input argument not specified // E_OUTOFMEMORY - Error allocating memory. // Other HRESULTs // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CClusCfgCredentials::SetDomainCredentials( LPCWSTR pcszCredentialsIn ) { TraceFunc( "[IClusSetCfgCredentials]" ); HRESULT hr = S_OK; WCHAR * pszBackslash = NULL; WCHAR * pszAtSign = NULL; BSTR bstrName = NULL; BSTR bstrDomain = NULL; if ( pcszCredentialsIn == NULL ) { hr = THR( E_INVALIDARG ); LogMsg( L"Server: CClusCfgCredentials::SetDomainCredentials() was given a NULL pointer argument." ); goto Cleanup; } // if: pszBackslash = wcschr( pcszCredentialsIn, L'\\' ); pszAtSign = wcschr( pcszCredentialsIn, L'@' ); // // Are the credentials in domain\user format? // if ( pszBackslash != NULL ) { *pszBackslash = L'\0'; pszBackslash++; // // If no domain was specified (e.g. the account was specified in the // '\account' form), use the domain of the local machine. // if ( *pszBackslash == L'\0' ) { // // A domain string was NOT specified in the credentials. // hr = THR( HrGetComputerName( ComputerNameDnsDomain, &bstrDomain, TRUE /*fBestEffortIn*/ ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: error getting the domain name } // if: no domain string was specified else { // // A domain string was specified in the credentials. // bstrDomain = TraceSysAllocString( pcszCredentialsIn ); if ( bstrDomain == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: } // if: domain string was specified bstrName = TraceSysAllocString( pszBackslash ); if ( bstrName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: } // if: domain\user format else if ( pszAtSign != NULL ) { // // Are the credentials in user@domain format? // *pszAtSign = L'\0'; pszAtSign++; bstrName = TraceSysAllocString( pcszCredentialsIn ); if ( bstrName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: bstrDomain = TraceSysAllocString( pszAtSign ); if ( bstrDomain == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: } // if: user@domain format else { // // Remember this as the user and get the FQDN for the local machine, // since this account is assumed to be an account local to this // machine. // bstrName = TraceSysAllocString( pcszCredentialsIn ); if ( bstrName == NULL ) { hr = THR( E_OUTOFMEMORY ); goto Cleanup; } // if: hr = THR( HrGetComputerName( ComputerNameDnsFullyQualified , &bstrDomain , FALSE // fBestEffortIn ) ); if ( FAILED( hr ) ) { goto Cleanup; } // if: error getting the FQDN for the computer } // neither domain\user nor user@domain format TraceSysFreeString( m_bstrAccountName ); m_bstrAccountName = bstrName; bstrName = NULL; TraceSysFreeString( m_bstrAccountDomain ); m_bstrAccountDomain = bstrDomain; bstrDomain = NULL; Cleanup: TraceSysFreeString( bstrName ); TraceSysFreeString( bstrDomain ); HRETURN( hr ); } //*** CClusCfgCredentials::SetDomainCredentials //*************************************************************************// ///////////////////////////////////////////////////////////////////////////// // CClusCfgCredentials class -- Private Methods. ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //++ // // CClusCfgCredentials::HrInit // // Description: // Initialize this component. // // Arguments: // None. // // Return Value: // S_OK - Success. // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CClusCfgCredentials::HrInit( void ) { TraceFunc( "" ); HRESULT hr = S_OK; HRETURN( hr ); } //*** CClusCfgCredentials::HrInit