//*************************************************************************** // // Copyright (c) 2000-2001 Microsoft Corporation, All Rights Reserved // // NtDomain.cpp // // Purpose: Nt domain discovery property set provider // //*************************************************************************** #include "precomp.h" #include #include "wbemnetapi32.h" #include #include "NtDomain.h" #define MAX_PROPS CWin32_NtDomain::e_End_Property_Marker #define MAX_PROP_IN_BYTES MAX_PROPS/8 + 1 #define _tobit( a ) ( 1 << a ) #define DOMAIN_PREPEND L"Domain: " #define DOMAIN_PREPEND_SIZE ((sizeof(DOMAIN_PREPEND)/sizeof(WCHAR)) - 1 ) // into strings.cpp LPCWSTR IDS_DomainControllerName = L"DomainControllerName" ; LPCWSTR IDS_DomainControllerAddress = L"DomainControllerAddress" ; LPCWSTR IDS_DomainControllerAddressType = L"DomainControllerAddressType" ; LPCWSTR IDS_DomainGuid = L"DomainGuid" ; LPCWSTR IDS_DomainName = L"DomainName" ; LPCWSTR IDS_DnsForestName = L"DnsForestName" ; LPCWSTR IDS_DS_PDC_Flag = L"DSPrimaryDomainControllerFlag" ; LPCWSTR IDS_DS_Writable_Flag = L"DSWritableFlag" ; LPCWSTR IDS_DS_GC_Flag = L"DSGlobalCatalogFlag" ; LPCWSTR IDS_DS_DS_Flag = L"DSDirectoryServiceFlag" ; LPCWSTR IDS_DS_KDC_Flag = L"DSKerberosDistributionCenterFlag" ; LPCWSTR IDS_DS_Timeserv_Flag = L"DSTimeServiceFlag" ; LPCWSTR IDS_DS_DNS_Controller_Flag = L"DSDnsControllerFlag" ; LPCWSTR IDS_DS_DNS_Domain_Flag = L"DSDnsDomainFlag" ; LPCWSTR IDS_DS_DNS_Forest_Flag = L"DSDnsForestFlag" ; LPCWSTR IDS_DcSiteName = L"DcSiteName" ; LPCWSTR IDS_ClientSiteName = L"ClientSiteName" ; // Property set declaration //========================= CWin32_NtDomain s_Win32_NtDomain( PROPSET_NAME_NTDOMAIN , IDS_CimWin32Namespace ) ; /***************************************************************************** * * FUNCTION : CWin32_NtDomain::CWin32_NtDomain * * DESCRIPTION : Constructor * * INPUTS : const CHString& strName - Name of the class. * * OUTPUTS : none * * RETURNS : nothing * * COMMENTS : Registers property set with framework * *****************************************************************************/ CWin32_NtDomain::CWin32_NtDomain ( LPCWSTR a_Name, LPCWSTR a_Namespace ) : Provider(a_Name, a_Namespace) { SetPropertyTable() ; } /***************************************************************************** * * FUNCTION : CWin32_NtDomain::~CWin32_NtDomain * * DESCRIPTION : Destructor * * INPUTS : none * * OUTPUTS : none * * RETURNS : nothing * * COMMENTS : Deregisters property set from framework * *****************************************************************************/ CWin32_NtDomain :: ~CWin32_NtDomain() { } // void CWin32_NtDomain::SetPropertyTable() { // property set names for query optimization m_pProps.SetSize( MAX_PROPS ) ; // Win32_NtDomain m_pProps[e_DomainControllerName] =(LPVOID) IDS_DomainControllerName; m_pProps[e_DomainControllerAddress] =(LPVOID) IDS_DomainControllerAddress; m_pProps[e_DomainControllerAddressType] =(LPVOID) IDS_DomainControllerAddressType; m_pProps[e_DomainGuid] =(LPVOID) IDS_DomainGuid; m_pProps[e_DomainName] =(LPVOID) IDS_DomainName; m_pProps[e_DnsForestName] =(LPVOID) IDS_DnsForestName; m_pProps[e_DS_PDC_Flag] =(LPVOID) IDS_DS_PDC_Flag; m_pProps[e_DS_Writable_Flag] =(LPVOID) IDS_DS_Writable_Flag; m_pProps[e_DS_GC_Flag] =(LPVOID) IDS_DS_GC_Flag; m_pProps[e_DS_DS_Flag] =(LPVOID) IDS_DS_DS_Flag; m_pProps[e_DS_KDC_Flag] =(LPVOID) IDS_DS_KDC_Flag; m_pProps[e_DS_Timeserv_Flag] =(LPVOID) IDS_DS_Timeserv_Flag; m_pProps[e_DS_DNS_Controller_Flag] =(LPVOID) IDS_DS_DNS_Controller_Flag; m_pProps[e_DS_DNS_Domain_Flag] =(LPVOID) IDS_DS_DNS_Domain_Flag; m_pProps[e_DS_DNS_Forest_Flag] =(LPVOID) IDS_DS_DNS_Forest_Flag; m_pProps[e_DcSiteName] =(LPVOID) IDS_DcSiteName; m_pProps[e_ClientSiteName] =(LPVOID) IDS_ClientSiteName; // CIM_System m_pProps[e_CreationClassName] =(LPVOID) IDS_CreationClassName; m_pProps[e_Name] =(LPVOID) IDS_Name; // key, override from CIM_ManagedSystemElement m_pProps[e_NameFormat] =(LPVOID) IDS_NameFormat; m_pProps[e_PrimaryOwnerContact] =(LPVOID) IDS_PrimaryOwnerContact; m_pProps[e_PrimaryOwnerName] =(LPVOID) IDS_PrimaryOwnerName; m_pProps[e_Roles] =(LPVOID) IDS_Roles; // CIM_ManagedSystemElement m_pProps[e_Caption] =(LPVOID) IDS_Caption; m_pProps[e_Description] =(LPVOID) IDS_Description; m_pProps[e_InstallDate] =(LPVOID) IDS_InstallDate; m_pProps[e_Status] =(LPVOID) IDS_Status; } //////////////////////////////////////////////////////////////////////// // // Function: CWin32_NtDomain::GetObject // // Inputs: CInstance* pInstance - Instance into which we // retrieve data. // // Outputs: None. // // Returns: HRESULT Success/Failure code. // // Comments: The calling function will commit the instance. // //////////////////////////////////////////////////////////////////////// #ifdef WIN9XONLY HRESULT CWin32_NtDomain::GetObject( CInstance *a_pInstance, long a_Flags, CFrameworkQuery &a_rQuery ) { return WBEM_S_NO_ERROR; } #endif #ifdef NTONLY HRESULT CWin32_NtDomain::GetObject( CInstance *a_pInstance, long a_Flags, CFrameworkQuery &a_rQuery ) { HRESULT t_hResult = WBEM_E_NOT_FOUND ; CHString t_chsDomainName ; CHString t_chsDomainKey ; DWORD t_dwBits ; CFrameworkQueryEx *t_pQuery2 ; std::vector<_bstr_t> t_vectorTrustList ; CNetAPI32 t_NetAPI ; if( ERROR_SUCCESS != t_NetAPI.Init() ) { return WBEM_E_FAILED ; } // the key a_pInstance->GetCHString( IDS_Name, t_chsDomainKey ) ; // NTD: begins the key -- this keeps this class from colliding // other CIM_System based classes if( 0 == _wcsnicmp(t_chsDomainKey, DOMAIN_PREPEND, DOMAIN_PREPEND_SIZE ) ) { t_chsDomainName = t_chsDomainKey.Mid( DOMAIN_PREPEND_SIZE ) ; } else { return WBEM_E_NOT_FOUND ; } // test resultant key if( t_chsDomainName.IsEmpty() ) { return WBEM_E_NOT_FOUND ; } // secure trusted domain list for key validation t_NetAPI.GetTrustedDomainsNT( t_vectorTrustList ) ; for( UINT t_u = 0L; t_u < t_vectorTrustList.size(); t_u++ ) { if( 0 == _wcsicmp( t_vectorTrustList[t_u], bstr_t( t_chsDomainName ) ) ) { // properties required t_pQuery2 = static_cast ( &a_rQuery ) ; t_pQuery2->GetPropertyBitMask( m_pProps, &t_dwBits ) ; t_hResult = GetDomainInfo( t_NetAPI, bstr_t( t_chsDomainName ), a_pInstance, t_dwBits ) ; if( WBEM_E_NOT_FOUND == t_hResult ) { // We have instantiated the domain. Couldn't obtain info though... t_hResult = WBEM_S_PARTIAL_RESULTS ; } break; } } return t_hResult ; } #endif //////////////////////////////////////////////////////////////////////// // // Function: CWin32_NtDomain::EnumerateInstances // // Inputs: MethodContext* a_pMethodContext - Context to enum // instance data in. // // Outputs: None. // // Returns: HRESULT Success/Failure code. // // Comments: None. // //////////////////////////////////////////////////////////////////////// #ifdef WIN9XONLY HRESULT CWin32_NtDomain::EnumerateInstances( MethodContext *a_pMethodContext, long a_Flags ) { return WBEM_S_NO_ERROR; } #endif #ifdef NTONLY HRESULT CWin32_NtDomain::EnumerateInstances( MethodContext *a_pMethodContext, long a_Flags ) { CNetAPI32 t_NetAPI ; if( ERROR_SUCCESS != t_NetAPI.Init() ) { return WBEM_E_FAILED ; } // Property mask -- include all DWORD t_dwBits = 0xffffffff; return EnumerateInstances( a_pMethodContext, a_Flags, t_NetAPI, t_dwBits ) ; } #endif /***************************************************************************** * * FUNCTION : CWin32_NtDomain::ExecQuery * * DESCRIPTION : Query optimizer * * INPUTS : * * OUTPUTS : * * RETURNS : * * COMMENTS : * *****************************************************************************/ #ifdef WIN9XONLY HRESULT CWin32_NtDomain::ExecQuery( MethodContext *a_pMethodContext, CFrameworkQuery &a_rQuery, long a_lFlags ) { return WBEM_S_NO_ERROR; } #endif #ifdef NTONLY HRESULT CWin32_NtDomain::ExecQuery( MethodContext *a_pMethodContext, CFrameworkQuery &a_rQuery, long a_lFlags ) { HRESULT t_hResult = WBEM_S_NO_ERROR ; HRESULT t_hPartialResult = WBEM_S_NO_ERROR ; DWORD t_dwBits ; CFrameworkQueryEx *t_pQuery2 ; std::vector<_bstr_t> t_vectorReqDomains ; std::vector<_bstr_t> t_vectorTrustList; CNetAPI32 t_NetAPI ; CHString t_chsDomainPrepend( DOMAIN_PREPEND ) ; if( ERROR_SUCCESS != t_NetAPI.Init() ) { return WBEM_E_FAILED ; } // properties required t_pQuery2 = static_cast ( &a_rQuery ) ; t_pQuery2->GetPropertyBitMask( m_pProps, &t_dwBits ) ; // keys supplied a_rQuery.GetValuesForProp( IDS_Name, t_vectorReqDomains ) ; // Note: the primary key has prepended chars to distinquish // these instances from other CIM_System instances. // if( t_vectorReqDomains.size() ) { // strip prepended characters for( int t_y = 0; t_y < t_vectorReqDomains.size(); t_y++ ) { if( DOMAIN_PREPEND_SIZE < t_vectorReqDomains[t_y].length() ) { // match on prepend? if( _wcsnicmp( (wchar_t*)t_vectorReqDomains[t_y], DOMAIN_PREPEND, DOMAIN_PREPEND_SIZE ) == 0 ) { t_vectorReqDomains[t_y] = ( (wchar_t*)t_vectorReqDomains[t_y] + DOMAIN_PREPEND_SIZE ) ; } } else { // does not contain the class prepend t_vectorReqDomains.erase( t_vectorReqDomains.begin() + t_y ) ; t_y--; } } } // If the primary key is not specified // then try for the alternate non key query. // // This is a requirement for assocation support // via CBinding as the linkage there is to DomainName if( !t_vectorReqDomains.size() ) { a_rQuery.GetValuesForProp( IDS_DomainName, t_vectorReqDomains ) ; } // General enum if query is ambigious if( !t_vectorReqDomains.size() ) { t_hResult = EnumerateInstances( a_pMethodContext, a_lFlags, t_NetAPI, t_dwBits ) ; } else { // smart ptr CInstancePtr t_pInst ; // secure trusted domain list t_NetAPI.GetTrustedDomainsNT( t_vectorTrustList ) ; // by query list for ( UINT t_uD = 0; t_uD < t_vectorReqDomains.size(); t_uD++ ) { // by Domain trust list for( UINT t_uT = 0L; t_uT < t_vectorTrustList.size(); t_uT++ ) { // Trust to request match if( 0 == _wcsicmp( t_vectorTrustList[t_uT], t_vectorReqDomains[t_uD] ) ) { t_pInst.Attach( CreateNewInstance( a_pMethodContext ) ) ; t_hResult = GetDomainInfo( t_NetAPI, t_vectorReqDomains[t_uD], t_pInst, t_dwBits ) ; if( SUCCEEDED( t_hResult ) ) { // the key t_pInst->SetCHString( IDS_Name, t_chsDomainPrepend + (wchar_t*)t_vectorReqDomains[t_uD] ) ; t_hResult = t_pInst->Commit() ; } else if( WBEM_E_NOT_FOUND == t_hResult ) { // We have instantiated the domain. Couldn't obtain info though... t_pInst->SetCHString( IDS_Name, t_chsDomainPrepend + (wchar_t*)t_vectorReqDomains[t_uD] ) ; t_hResult = t_pInst->Commit() ; t_hPartialResult = WBEM_S_PARTIAL_RESULTS ; } break ; } } if( FAILED( t_hResult ) ) { break ; } } } return ( WBEM_S_NO_ERROR != t_hResult ) ? t_hResult : t_hPartialResult ; } #endif // #ifdef NTONLY HRESULT CWin32_NtDomain::EnumerateInstances( MethodContext *a_pMethodContext, long a_Flags, CNetAPI32 &a_rNetAPI, DWORD a_dwProps ) { HRESULT t_hResult = WBEM_S_NO_ERROR ; HRESULT t_hPartialResult = WBEM_S_NO_ERROR ; std::vector<_bstr_t> t_vectorTrustList; CHString t_chsDomainPrepend( DOMAIN_PREPEND ) ; // smart ptr CInstancePtr t_pInst ; // secure trusted domain list a_rNetAPI.GetTrustedDomainsNT( t_vectorTrustList ) ; for( UINT t_u = 0L; t_u < t_vectorTrustList.size(); t_u++ ) { t_pInst.Attach( CreateNewInstance( a_pMethodContext ) ) ; t_hResult = GetDomainInfo( a_rNetAPI, t_vectorTrustList[ t_u ], t_pInst, a_dwProps ) ; if( SUCCEEDED( t_hResult ) ) { // the key t_pInst->SetCHString( IDS_Name, t_chsDomainPrepend + (wchar_t*)t_vectorTrustList[t_u] ) ; t_hResult = t_pInst->Commit() ; } else if( WBEM_E_NOT_FOUND == t_hResult ) { // the key. We have instantiated the domain. Couldn't obtain info though... t_pInst->SetCHString( IDS_Name, t_chsDomainPrepend + (wchar_t*)t_vectorTrustList[t_u] ) ; t_hResult = t_pInst->Commit() ; t_hPartialResult = WBEM_S_PARTIAL_RESULTS ; } else { break ; } } return ( WBEM_S_NO_ERROR != t_hResult ) ? t_hResult : t_hPartialResult ; } #endif // #ifdef NTONLY HRESULT CWin32_NtDomain::GetDomainInfo( CNetAPI32 &a_rNetAPI, bstr_t &a_bstrDomainName, CInstance *a_pInst, DWORD a_dwProps ) { HRESULT t_hResult = WBEM_S_NO_ERROR ; if( a_bstrDomainName.length() ) { ULONG t_uFlags = 0L ; DOMAIN_CONTROLLER_INFO *t_pDCInfo = NULL ; DWORD t_dwNetApiResult = 0 ; try { // avoid the NetAPI call if not needed if( a_dwProps & ( _tobit( e_DomainControllerName ) | _tobit( e_DomainControllerAddress ) | _tobit( e_DomainControllerAddressType ) | _tobit( e_DomainGuid ) | _tobit( e_DomainName ) | _tobit( e_DnsForestName ) | _tobit( e_DS_PDC_Flag ) | _tobit( e_DS_Writable_Flag ) | _tobit( e_DS_GC_Flag ) | _tobit( e_DS_DS_Flag ) | _tobit( e_DS_KDC_Flag ) | _tobit( e_DS_Timeserv_Flag ) | _tobit( e_DS_DNS_Controller_Flag ) | _tobit( e_DS_DNS_Domain_Flag ) | _tobit( e_DS_DNS_Forest_Flag ) | _tobit( e_DcSiteName ) | _tobit( e_ClientSiteName ) ) ) { // if requesting domain IP if( a_dwProps & _tobit( e_DomainControllerAddress ) ) { t_uFlags |= DS_IP_REQUIRED ; } t_dwNetApiResult = a_rNetAPI.DsGetDcName( NULL, (wchar_t*)a_bstrDomainName, NULL, NULL, t_uFlags, &t_pDCInfo ) ; // force it if not cached if( NO_ERROR != t_dwNetApiResult ) { t_uFlags |= DS_FORCE_REDISCOVERY ; t_dwNetApiResult = a_rNetAPI.DsGetDcName( NULL, (wchar_t*)a_bstrDomainName, NULL, NULL, t_uFlags, &t_pDCInfo ) ; } if( ( NO_ERROR == t_dwNetApiResult ) && t_pDCInfo ) { // DomainControllerName if( a_dwProps & _tobit( e_DomainControllerName ) ) { if( t_pDCInfo->DomainControllerName ) { a_pInst->SetWCHARSplat( IDS_DomainControllerName, t_pDCInfo->DomainControllerName ) ; } } // DomainControllerAddress if( a_dwProps & _tobit( e_DomainControllerAddress ) ) { if( t_pDCInfo->DomainControllerAddress ) { a_pInst->SetWCHARSplat( IDS_DomainControllerAddress, t_pDCInfo->DomainControllerAddress ) ; } // DomainControllerAddressType, dependent on DS_IP_REQUIRED request if( a_dwProps & _tobit( e_DomainControllerAddressType ) ) { a_pInst->SetDWORD( IDS_DomainControllerAddressType, t_pDCInfo->DomainControllerAddressType ) ; } } // DomainGuid if( a_dwProps & _tobit( e_DomainGuid ) ) { GUID t_NullGuid ; memset( &t_NullGuid, 0, sizeof( t_NullGuid ) ) ; if( !IsEqualGUID( t_NullGuid, t_pDCInfo->DomainGuid ) ) { WCHAR t_cGuid[ 128 ] ; StringFromGUID2( t_pDCInfo->DomainGuid, t_cGuid, sizeof( t_cGuid ) / sizeof (WCHAR) ) ; a_pInst->SetWCHARSplat( IDS_DomainGuid, t_cGuid ) ; } } // DomainName if( a_dwProps & _tobit( e_DomainName ) ) { if( t_pDCInfo->DomainName ) { a_pInst->SetWCHARSplat( IDS_DomainName, t_pDCInfo->DomainName ) ; } } // DnsForestName if( a_dwProps & _tobit( e_DnsForestName ) ) { if( t_pDCInfo->DnsForestName ) { a_pInst->SetWCHARSplat( IDS_DnsForestName, t_pDCInfo->DnsForestName ) ; } } // DSPrimaryDomainControllerFlag if( a_dwProps & _tobit( e_DS_PDC_Flag ) ) { a_pInst->Setbool( IDS_DS_PDC_Flag, (bool)(t_pDCInfo->Flags & DS_PDC_FLAG) ) ; } // DSWritableFlag if( a_dwProps & _tobit( e_DS_Writable_Flag ) ) { a_pInst->Setbool( IDS_DS_Writable_Flag, (bool)(t_pDCInfo->Flags & DS_WRITABLE_FLAG) ) ; } // DSGlobalCatalogFlag if( a_dwProps & _tobit( e_DS_GC_Flag ) ) { a_pInst->Setbool( IDS_DS_GC_Flag, (bool)(t_pDCInfo->Flags & DS_GC_FLAG) ) ; } // DSDirectoryServiceFlag if( a_dwProps & _tobit( e_DS_DS_Flag ) ) { a_pInst->Setbool( IDS_DS_DS_Flag, (bool)(t_pDCInfo->Flags & DS_DS_FLAG) ) ; } // DSKerberosDistributionCenterFlag if( a_dwProps & _tobit( e_DS_KDC_Flag ) ) { a_pInst->Setbool( IDS_DS_KDC_Flag, (bool)(t_pDCInfo->Flags & DS_KDC_FLAG) ) ; } // DSTimeServiceFlag if( a_dwProps & _tobit( e_DS_Timeserv_Flag ) ) { a_pInst->Setbool( IDS_DS_Timeserv_Flag, (bool)(t_pDCInfo->Flags & DS_TIMESERV_FLAG) ) ; } // DSDnsControllerFlag if( a_dwProps & _tobit( e_DS_DNS_Controller_Flag ) ) { a_pInst->Setbool( IDS_DS_DNS_Controller_Flag, (bool)(t_pDCInfo->Flags & DS_DNS_CONTROLLER_FLAG) ) ; } // DSDnsDomainFlag if( a_dwProps & _tobit( e_DS_DNS_Domain_Flag ) ) { a_pInst->Setbool( IDS_DS_DNS_Domain_Flag, (bool)(t_pDCInfo->Flags & DS_DNS_DOMAIN_FLAG) ) ; } // DSDnsForestFlag if( a_dwProps & _tobit( e_DS_DNS_Forest_Flag ) ) { a_pInst->Setbool( IDS_DS_DNS_Forest_Flag, (bool)(t_pDCInfo->Flags & DS_DNS_FOREST_FLAG) ) ; } // DcSiteName if( a_dwProps & _tobit( e_DcSiteName ) ) { if( t_pDCInfo->DcSiteName ) { a_pInst->SetWCHARSplat( IDS_DcSiteName, t_pDCInfo->DcSiteName ) ; } } // ClientSiteName if( a_dwProps & _tobit( e_ClientSiteName ) ) { if( t_pDCInfo->ClientSiteName ) { a_pInst->SetWCHARSplat( IDS_ClientSiteName, t_pDCInfo->ClientSiteName ) ; } } t_hResult = WBEM_S_NO_ERROR ; } else if( ERROR_NOT_ENOUGH_MEMORY == t_dwNetApiResult ) { t_hResult = WBEM_E_OUT_OF_MEMORY ; } else { t_hResult = WBEM_E_NOT_FOUND ; } } // CIM_System follows // CreationClassName if( a_dwProps & _tobit( e_CreationClassName ) ) { a_pInst->SetWCHARSplat( IDS_CreationClassName, PROPSET_NAME_NTDOMAIN ) ; } // CIM_System::Name is the key // TODO: // e_NameFormat, IDS_NameFormat // e_PrimaryOwnerContact, IDS_PrimaryOwnerContact // e_PrimaryOwnerName, IDS_PrimaryOwnerName // e_Roles, IDS_Roles // CIM_ManagedSystemElement follows // Caption if( a_dwProps & _tobit( e_Caption ) ) { // REVIEW: a_pInst->SetWCHARSplat( IDS_Caption, (wchar_t*)a_bstrDomainName ) ; } // Description if( a_dwProps & _tobit( e_Description ) ) { // REVIEW: a_pInst->SetWCHARSplat( IDS_Description, (wchar_t*)a_bstrDomainName ) ; } // Status if( a_dwProps & _tobit( e_Status ) ) { if( NO_ERROR == t_dwNetApiResult ) { // REVIEW: a_pInst->SetCHString ( IDS_Status , IDS_STATUS_OK ) ; } else { // REVIEW: a_pInst->SetCHString ( IDS_Status , IDS_STATUS_Unknown ) ; } } // TODO: // e_InstallDate, IDS_InstallDate } catch(...) { if( t_pDCInfo ) { a_rNetAPI.NetApiBufferFree( t_pDCInfo ) ; } throw; } if( t_pDCInfo ) { a_rNetAPI.NetApiBufferFree( t_pDCInfo ) ; t_pDCInfo = NULL ; } } else // NULL domain { t_hResult = WBEM_E_NOT_FOUND ; } return t_hResult ; } #endif