Leaked source code of windows server 2003
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.
 
 
 
 
 
 

907 lines
28 KiB

///////////////////////////////////////////////////////////////////////////
//
// Copyright(C) 1997-1998 Microsoft Corporation all rights reserved.
//
// Module: sdomachine.cpp
//
// Project: Everest
//
// Description: SDO Machine Implementation
//
// Author: TLP 9/1/98
//
///////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <ias.h>
#include <lm.h>
#include <dsrole.h>
#include "sdomachine.h"
#include "sdofactory.h"
#include "sdo.h"
#include "dspath.h"
#include "sdodictionary.h"
#include "sdoschema.h"
#include "activeds.h"
HRESULT
WINAPI
IASGetLDAPPathForUser(
PCWSTR computerName,
PCWSTR userName,
BSTR* path
) throw ()
{
HRESULT hr;
// Check the pointers.
if (!computerName || !userName || !path) { return E_POINTER; }
// Check the string lengths, so we don't have to worry about overflow.
if (wcslen(computerName) > MAX_PATH || wcslen(userName) > MAX_PATH)
{ return E_INVALIDARG; }
// Initialize the out parameter.
*path = NULL;
// Form the LDAP path for the target computer.
WCHAR root[8 + MAX_PATH];
wcscat(wcscpy(root, L"LDAP://"), computerName);
// Get the IDirectorySearch interface.
CComPtr<IDirectorySearch> search;
// tperraut 453050
hr = ADsOpenObject(
root,
NULL,
NULL,
ADS_SECURE_AUTHENTICATION |
ADS_USE_SIGNING |
ADS_USE_SEALING,
__uuidof(IDirectorySearch),
(PVOID*)&search
);
if (FAILED(hr)) { return hr; }
// Form the search filter.
WCHAR filter[18 + MAX_PATH];
wcscat(wcscat(wcscpy(filter, L"(sAMAccountName="), userName), L")");
// Execute the search.
PWSTR attrs[] = { L"distinguishedName" };
ADS_SEARCH_HANDLE result;
hr = search->ExecuteSearch(
filter,
attrs,
1,
&result
);
if (FAILED(hr)) { return hr; }
// Get the first row.
hr = search->GetFirstRow(result);
if (SUCCEEDED(hr))
{
// Get the column containing the distinguishedName.
ADS_SEARCH_COLUMN column;
hr = search->GetColumn(result, attrs[0], &column);
if (SUCCEEDED(hr))
{
// Sanity check the struct.
if (column.dwADsType == ADSTYPE_DN_STRING && column.dwNumValues)
{
// Extract the DN.
PCWSTR dn = column.pADsValues[0].DNString;
// Get the Pathname object.
IADsPathname* pathname;
hr = CoCreateInstance(
__uuidof(Pathname),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IADsPathname),
(PVOID*)&pathname
);
if (SUCCEEDED(hr))
{
do
{
/////////
// Build the ADSI path.
/////////
hr = pathname->Set(L"LDAP", ADS_SETTYPE_PROVIDER);
if (FAILED(hr)) { break; }
hr = pathname->Set((PWSTR)computerName, ADS_SETTYPE_SERVER);
if (FAILED(hr)) { break; }
hr = pathname->Set((PWSTR)dn, ADS_SETTYPE_DN);
if (FAILED(hr)) { break; }
hr = pathname->Retrieve(ADS_FORMAT_WINDOWS, path);
} while (FALSE);
pathname->Release();
}
}
else
{
// We got back a bogus ADS_SEARCH_COLUMN struct.
hr = E_FAIL;
}
// Free the column data.
search->FreeColumn(&column);
}
}
// Close the search handle.
search->CloseSearchHandle(result);
return hr;
}
//////////////////////////////////////////////////////////////////////////////
CSdoMachine::CSdoMachine()
: m_fAttached(false),
m_fSchemaInitialized(false),
m_pSdoSchema(NULL),
m_pSdoDictionary(NULL),
dsType(Directory_Unknown)
{
memset(&m_Limits, 0, sizeof(m_Limits));
}
//////////////////////////////////////////////////////////////////////////////
CSdoMachine::~CSdoMachine()
{
if ( m_fAttached )
{
m_dsIAS.Disconnect();
m_dsAD.Disconnect();
m_pSdoSchema->Release();
if ( m_pSdoDictionary )
m_pSdoDictionary->Release();
IASUninitialize();
}
}
//////////////////////
// ISdoMachine Methods
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSdoMachine::Attach(
/*[in]*/ BSTR computerName
)
{
CSdoLock theLock(*this);
_ASSERT( ! m_fAttached );
if ( m_fAttached )
return E_FAIL;
HRESULT hr = E_FAIL;
try
{
if ( computerName )
IASTracePrintf("Machine SDO is attempting to attach to computer: '%ls'...", computerName);
else
IASTracePrintf("Machine SDO is attempting to attach to the local computer...");
IASTracePrintf("Machine SDO is initializing the IAS support services...");
if ( IASInitialize() )
{
hr = m_dsIAS.Connect(computerName, NULL, NULL);
if ( SUCCEEDED(hr) )
{
DWORD error = IASGetProductLimits(computerName, &m_Limits);
if (error == NO_ERROR)
{
IASTracePrintf("Machine SDO is creating the SDO schema...");
hr = CreateSDOSchema();
if ( SUCCEEDED(hr) )
{
IASTracePrintf("Machine SDO has successfully attached to computer: '%ls'...",m_dsIAS.GetServerName());
m_fAttached = true;
}
else
{
m_dsIAS.Disconnect();
IASUninitialize();
}
}
else
{
hr = HRESULT_FROM_WIN32(error);
m_dsIAS.Disconnect();
IASUninitialize();
}
}
else
{
IASTracePrintf("Error in Machine SDO - Attach() - Could not connect to IAS data store...");
}
}
else
{
IASTracePrintf("Error in Machine SDO - Attach() - Could not initialize IAS support services...");
}
}
catch(...)
{
IASTracePrintf("Error in Machine SDO - Attach() - Caught unknown exception...");
hr = E_UNEXPECTED;
}
return hr;
}
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSdoMachine::GetDictionarySDO(
/*[out]*/ IUnknown** ppDictionarySdo
)
{
CSdoLock theLock(*this);
IASTracePrintf("Machine SDO is retrieving the Dictionary SDO...");
HRESULT hr = S_OK;
try
{
do
{
// Check preconditions
//
_ASSERT( m_fAttached );
if ( ! m_fAttached )
{
hr = E_FAIL;
break;
}
_ASSERT( NULL != ppDictionarySdo );
if ( NULL == ppDictionarySdo )
{
hr = E_POINTER;
break;
}
// The dictionary is a singleton...
//
if (NULL == m_pSdoDictionary)
{
hr = InitializeSDOSchema();
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetDictionarySDO() - Could not initialize the SDO schema...");
break;
}
// Create the Dictionary SDO
CComPtr<SdoDictionary> pSdoDictionary;
hr = SdoDictionary::createInstance(
m_dsIAS.GetConfigPath(),
!m_dsIAS.IsRemoteServer(),
(SdoDictionary**)&m_pSdoDictionary
);
if (FAILED(hr))
{
IASTraceFailure("SdoDictionary::createInstance", hr);
break;
}
}
// Return the dictionary interface to the caller
//
(*ppDictionarySdo = m_pSdoDictionary)->AddRef();
} while ( FALSE );
}
catch(...)
{
IASTracePrintf("Error in Machine SDO - GetDictionarySDO() - Caught unknown exception...");
hr = E_UNEXPECTED;
}
return hr;
}
const wchar_t g_IASService[] = L"IAS";
const wchar_t g_RASService[] = L"RemoteAccess";
const wchar_t g_Sentinel[] = L"Sentinel";
LPCWSTR CSdoMachine::m_SupportedServices[MACHINE_MAX_SERVICES] = {
g_IASService,
g_RASService,
g_Sentinel
};
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSdoMachine::GetServiceSDO(
/*[in]*/ IASDATASTORE dataStore,
/*[in]*/ BSTR serviceName,
/*[out]*/ IUnknown** ppServiceSdo
)
{
CSdoLock theLock(*this);
_ASSERT( m_fAttached );
if ( ! m_fAttached )
return E_FAIL;
_ASSERT(
( DATA_STORE_LOCAL == dataStore || DATA_STORE_DIRECTORY == dataStore ) &&
NULL != serviceName &&
NULL != ppServiceSdo
);
if ( ( DATA_STORE_LOCAL != dataStore && DATA_STORE_DIRECTORY != dataStore ) ||
NULL == serviceName ||
NULL == ppServiceSdo
)
{
return E_INVALIDARG;
}
IASTracePrintf("Machine SDO is attempting to retrieve the Service SDO for service: %ls...", serviceName);
int i;
for ( i = 0; i < MACHINE_MAX_SERVICES; i++ )
{
if ( ! lstrcmp(serviceName, m_SupportedServices[i]) )
{
break;
}
else
{
if ( ! lstrcmp(m_SupportedServices[i], g_Sentinel ) )
return E_INVALIDARG;
}
}
HRESULT hr = E_INVALIDARG;
try
{
do
{
hr = InitializeSDOSchema();
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetServiceSDO() - Could not initialize the SDO schema...");
break;
}
CComBSTR bstrServiceName(DS_OBJECT_SERVICE);
if (!bstrServiceName)
{
hr = E_OUTOFMEMORY;
break;
}
CComPtr<IDataStoreObject> pDSObject;
hr = (m_dsIAS.GetDSRootContainer())->Item(bstrServiceName, &pDSObject);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetServiceSDO() - Could not locate IAS service data store...");
break;
}
CComPtr<ISdo> pSdoService;
pSdoService.p = ::MakeSDO(
serviceName,
SDO_PROG_ID_SERVICE,
static_cast<ISdoMachine*>(this),
pDSObject,
NULL,
false
);
if ( NULL == pSdoService.p )
{
IASTracePrintf("Error in Machine SDO - GetServiceSDO() - MakeSDO() failed...");
hr = E_FAIL;
break;
}
hr = pSdoService->QueryInterface(IID_IDispatch, (void**)ppServiceSdo);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetServiceSDO() - QueryInterface(IDispatch) failed...");
break;
}
} while ( FALSE );
}
catch(...)
{
IASTracePrintf("Error in Machine SDO - GetServiceSDO() - Caught unknown exception...");
hr = E_UNEXPECTED;
}
return hr;
}
//////////////////////////////////////////////////////////////////////////////
const wchar_t DOWNLEVEL_NAME[] = L"downlevel";
STDMETHODIMP CSdoMachine::GetUserSDO(
/*[in]*/ IASDATASTORE eDataStore,
/*[in]*/ BSTR bstrUserName,
/*[out]*/ IUnknown** ppUserSdo
)
{
CSdoLock theLock(*this);
_ASSERT( m_fAttached );
if ( ! m_fAttached )
return E_FAIL;
_ASSERT(
( DATA_STORE_LOCAL == eDataStore || DATA_STORE_DIRECTORY == eDataStore ) &&
NULL != bstrUserName &&
NULL != ppUserSdo
);
if ( ( DATA_STORE_LOCAL != eDataStore && DATA_STORE_DIRECTORY != eDataStore ) ||
NULL == bstrUserName ||
NULL == ppUserSdo
)
return E_INVALIDARG;
HRESULT hr = E_FAIL;
// Map local users to the DS if we're attached to a machine with
// a directory.
if (eDataStore == DATA_STORE_LOCAL && hasDirectory())
{
eDataStore = DATA_STORE_DIRECTORY;
}
// If we're connecting to a directory and the username doesn't begin with
// "LDAP://", then we'll assume it's a SAM account name.
BSTR ldapPath = NULL;
if (eDataStore == DATA_STORE_DIRECTORY &&
wcsncmp(bstrUserName, L"LDAP://", 7))
{
hr = IASGetLDAPPathForUser(
m_dsIAS.GetServerName(),
bstrUserName,
&ldapPath
);
if (FAILED(hr)) { return hr; }
bstrUserName = ldapPath;
}
IASTracePrintf("Machine SDO is attempting to retrieve the RAS User SDO for user: %ls...", bstrUserName);
ISdo* pSdoUser = NULL;
try
{
do
{
// Get the IDataStoreObject interface for the new User SDO.
// We'll use the IDataStoreObject interface to read/write User SDO properties.
//
bool fUseDownLevelAPI = false;
bool fUseNetAPI = true;
CComPtr<IDataStoreObject> pDSObject;
_variant_t vtSAMAccountName;
if ( DATA_STORE_DIRECTORY == eDataStore )
{
// Make sure we're connected to the directory
//
if ( ! m_dsAD.IsConnected() )
{
hr = m_dsAD.Connect(m_dsIAS.GetServerName(), NULL, NULL);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not connect to the directory data store...");
break;
}
}
// Make sure it's initialized.
hr = m_dsAD.InitializeDS();
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not initialize the directory data store...");
break;
}
// Get the user object from the directory
//
hr = (m_dsAD.GetDSRoot())->OpenObject(bstrUserName, &pDSObject);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not retrieve user object from DS...");
break;
}
// If we're connected to a dc in a mixed domain we'll need to first get the users
// SAM account name from the user object in the active directory and then treat the
// GetUserSDO() call as if the caller specified DATA_STORE_LOCAL. We also use
// downlevel APIs (SAM) because its a mixed domain.
//
if ( m_dsAD.IsMixedMode() )
{
IASTracePrintf("Machine SDO - GetUserSDO() - Current DC (Server) %ls is in a mixed mode domain...", m_dsAD.GetServerName());
hr = pDSObject->GetValue(IAS_NTDS_SAM_ACCOUNT_NAME, &vtSAMAccountName);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Server SDO - GetUserSDO() - Could not retrieve users SAM account name...");
break;
}
bstrUserName = V_BSTR(&vtSAMAccountName);
fUseDownLevelAPI = true;
pDSObject.Release();
IASTracePrintf("Server SDO - GetUserSDO() - User's SAM account name is: %ls...", (LPWSTR)bstrUserName);
}
else
{
// Use the directory data store object for all subsequent property read/write
// operations on this User SDO.
//
IASTracePrintf("Server SDO - GetUserSDO() - Using active directory for user properties...");
fUseNetAPI = false;
}
}
if ( fUseNetAPI )
{
// Create the net data store and aquire the data store object interfaces
// we'll use to complete the GetUserSDO() operation
//
CComPtr<IDataStore2> pDSNet;
hr = CoCreateInstance(
__uuidof(NetDataStore),
NULL,
CLSCTX_INPROC_SERVER,
IID_IDataStore2,
(void**)&pDSNet
);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - CoCreateInstance(NetDataStore) failed...");
break;
}
hr = pDSNet->Initialize(NULL, NULL, NULL);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not initialize net data store...");
break;
}
CComPtr<IDataStoreObject> pDSRootObject;
hr = pDSNet->get_Root(&pDSRootObject);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not get Root object from net data store...");
break;
}
CComPtr<IDataStoreContainer> pDSContainer;
hr = pDSRootObject->QueryInterface(IID_IDataStoreContainer, (void**)&pDSContainer);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - QueryInterface(IID_IDataStoreContainer) failed...");
break;
}
// Get the name of the attached computer and use it to aquire a "Server"
// (machine) object from the data store.
//
CComPtr<IDataStoreObject> pDSObjectMachine;
if ( fUseDownLevelAPI )
{
_bstr_t bstrServerName = m_dsAD.GetServerName();
IASTracePrintf("Machine SDO - GetUserSDO() - Using server %ls with downlevel APIs...", (LPWSTR)bstrServerName);
hr = pDSContainer->Item(bstrServerName, &pDSObjectMachine);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not obtain server object from net data store...");
break;
}
_bstr_t bstrDownLevel = DOWNLEVEL_NAME;
_variant_t vtDownLevel;
V_BOOL(&vtDownLevel) = VARIANT_TRUE;
V_VT(&vtDownLevel) = VT_BOOL;
hr = pDSObjectMachine->PutValue(bstrDownLevel, &vtDownLevel);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not set downlevel data store mode...");
break;
}
}
else
{
_bstr_t bstrServerName = m_dsIAS.GetServerName();
IASTracePrintf("Machine SDO - GetUserSDO() - Using server %ls with Net APIs...", (LPWSTR)bstrServerName);
hr = pDSContainer->Item(bstrServerName, &pDSObjectMachine);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not obtain server object from data store...");
break;
}
}
pDSContainer.Release();
// Get "User" object from the "Server" object. We'll use the "User" object in
// all subsequent read/write operations on the User SDO.
//
hr = pDSObjectMachine->QueryInterface(IID_IDataStoreContainer, (void**)&pDSContainer);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - QueryInterface(IID_IDataStoreContainer) failed...");
break;
}
hr = pDSContainer->Item(bstrUserName, &pDSObject);
if ( FAILED(hr) )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - Could not obtain user object from data store...");
break;
}
}
// Create and initialize the User SDO
//
pSdoUser = ::MakeSDO(
NULL,
SDO_PROG_ID_USER,
static_cast<ISdoMachine*>(this),
pDSObject,
NULL,
false
);
if ( NULL == pSdoUser )
{
IASTracePrintf("Error in Machine SDO - GetUserSDO() - MakeSDO() failed...");
hr = E_FAIL;
}
else
{
CComPtr<IDispatch> pSdoDispatch;
hr = pSdoUser->QueryInterface(IID_IDispatch, (void**)&pSdoDispatch);
if ( FAILED(hr) )
IASTracePrintf("Error in Machine SDO - GetUserSDO() - QueryInterface(IDispatch) failed...");
else
(*ppUserSdo = pSdoDispatch)->AddRef();
}
}
while ( FALSE);
}
catch(...)
{
IASTracePrintf("Error in Server SDO - GetUserSDO() - Caught unknown exception...");
hr = E_FAIL;
}
if ( pSdoUser )
pSdoUser->Release();
if (ldapPath) { SysFreeString(ldapPath); }
return hr;
}
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSdoMachine::GetOSType(
/*[out]*/ IASOSTYPE* eOSType
)
{
CSdoLock theLock(*this);
_ASSERT( m_fAttached );
if ( ! m_fAttached )
return E_FAIL;
_ASSERT( NULL != eOSType );
if ( NULL == eOSType )
return E_INVALIDARG;
// Get the OS info now
//
HRESULT hr = m_objServerInfo.GetOSInfo (
(LPWSTR)m_dsIAS.GetServerName(),
eOSType
);
if ( FAILED (hr) )
IASTracePrintf("Error in Machine SDO - GetOSType() failed with error: %lx...", hr);
return hr;
}
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSdoMachine::GetDomainType(
/*[out]*/ IASDOMAINTYPE* eDomainType
)
{
CSdoLock theLock(*this);
_ASSERT( m_fAttached );
if ( ! m_fAttached )
return E_FAIL;
_ASSERT( NULL != eDomainType );
if ( NULL == eDomainType )
return E_INVALIDARG;
HRESULT hr = m_objServerInfo.GetDomainInfo (
OBJECT_TYPE_COMPUTER,
(LPWSTR)m_dsIAS.GetServerName(),
eDomainType
);
if (FAILED (hr))
IASTracePrintf("Error in Machine SDO - GetDomainType() - failed with error: %lx...", hr);
return hr;
}
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSdoMachine::IsDirectoryAvailable(
/*[out]*/ VARIANT_BOOL* boolDirectoryAvailable
)
{
CSdoLock theLock(*this);
_ASSERT( m_fAttached );
if ( ! m_fAttached )
return E_FAIL;
_ASSERT( NULL != boolDirectoryAvailable );
if ( NULL == boolDirectoryAvailable )
return E_INVALIDARG;
*boolDirectoryAvailable = VARIANT_FALSE;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSdoMachine::GetAttachedComputer(
/*[out]*/ BSTR* bstrComputerName
)
{
CSdoLock theLock(*this);
_ASSERT( m_fAttached );
if ( ! m_fAttached )
return E_FAIL;
_ASSERT( NULL != bstrComputerName );
if ( NULL == bstrComputerName )
return E_INVALIDARG;
*bstrComputerName = SysAllocString(m_dsIAS.GetServerName());
if ( NULL != *bstrComputerName )
return S_OK;
else
return E_OUTOFMEMORY;
}
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CSdoMachine::GetSDOSchema(
/*[out]*/ IUnknown** ppSDOSchema
)
{
CSdoLock theLock(*this);
_ASSERT( m_fAttached );
if ( ! m_fAttached )
return E_FAIL;
_ASSERT( NULL != ppSDOSchema );
if ( NULL == ppSDOSchema )
return E_INVALIDARG;
(*ppSDOSchema = m_pSdoSchema)->AddRef();
return S_OK;
}
STDMETHODIMP CSdoMachine::get_Limits(IAS_PRODUCT_LIMITS* pVal)
{
if (pVal == 0)
{
return E_POINTER;
}
*pVal = m_Limits;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////
// Private member functions
///////////////////////////////////////////////////////////////////////////////
HRESULT CSdoMachine::CreateSDOSchema()
{
auto_ptr<SDO_SCHEMA_OBJ> pSchema (new SDO_SCHEMA_OBJ);
HRESULT hr = pSchema->Initialize(NULL);
if ( SUCCEEDED(hr) )
m_pSdoSchema = dynamic_cast<ISdoSchema*>(pSchema.release());
return hr;
}
///////////////////////////////////////////////////////////////////////////////
HRESULT CSdoMachine::InitializeSDOSchema()
{
HRESULT hr = S_OK;
if ( ! m_fSchemaInitialized )
{
// First initialize the IAS data store
//
hr = m_dsIAS.InitializeDS();
if ( SUCCEEDED(hr) )
{
// Get the root data store object for the SDO schema
//
CComPtr<IDataStoreContainer> pDSRootContainer = m_dsIAS.GetDSRootContainer();
_bstr_t bstrSchemaName = SDO_SCHEMA_ROOT_OBJECT;
CComPtr<IDataStoreObject> pSchemaDataStore;
hr = pDSRootContainer->Item(bstrSchemaName, &pSchemaDataStore);
if ( SUCCEEDED(hr) )
{
// Initialize the SDO schema from the SDO schema data store
//
PSDO_SCHEMA_OBJ pSchema = dynamic_cast<PSDO_SCHEMA_OBJ>(m_pSdoSchema);
hr = pSchema->Initialize(pSchemaDataStore);
if ( SUCCEEDED(hr) )
m_fSchemaInitialized = true;
}
else
{
IASTracePrintf("Error in Machine SDO - InitializeSDOSchema() - Could not locate schema data store...");
}
}
else
{
IASTracePrintf("Error in Machine SDO - InitializeSDOSchema() - Could not initialize the IAS data store...");
}
}
return hr;
}
// Returns TRUE if the attached machine has a DS.
BOOL CSdoMachine::hasDirectory() throw ()
{
if (dsType == Directory_Unknown)
{
PDSROLE_PRIMARY_DOMAIN_INFO_BASIC info;
DWORD error = DsRoleGetPrimaryDomainInformation(
m_dsIAS.GetServerName(),
DsRolePrimaryDomainInfoBasic,
(PBYTE*)&info
);
if (error == NO_ERROR)
{
if (info->Flags & DSROLE_PRIMARY_DS_RUNNING)
{
dsType = Directory_Available;
}
else
{
dsType = Directory_None;
}
NetApiBufferFree(info);
}
}
return dsType == Directory_Available;
}