|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 2000.
//
// File: cconnect.cxx
//
// Contents: LDAP Connection object - this object implements the
// IUmiConnection interface.
//
// Functions: TBD.
//
// History: 03-03-00 AjayR Created.
//
//----------------------------------------------------------------------------
#include "ldap.hxx"
//+---------------------------------------------------------------------------
// Function: CLDAPConObject::CLDAPConObject
//
// Synopsis: Constructor
//
// Arguments: None
//
// Returns: N/A
//
// Modifies: N/A
//
//----------------------------------------------------------------------------
CLDAPConObject::CLDAPConObject(): _pPropMgr(NULL), _fConnected(FALSE), _pLdapHandle(NULL), _ulErrorStatus(0) { }
//+---------------------------------------------------------------------------
// Function: CLDAPConObject::~CLDAPConObject
//
// Synopsis: Destructor
//
// Arguments: None
//
// Returns: N/A
//
// Modifies: N/A
//
//----------------------------------------------------------------------------
CLDAPConObject::~CLDAPConObject() { delete _pPropMgr; //
// Close the handle if needed - this will deref and free if appropriate.
//
if (_pLdapHandle) { LdapCloseObject(_pLdapHandle); _pLdapHandle = NULL; } }
//+---------------------------------------------------------------------------
// Function: CLDAPConObject::CreateConnectionObject
//
// Synopsis: Static allocation routine for connection object.
//
// Arguments: CLDAPConObject * --- contains new connection object
// PADSLDP --- ldap handle defaulted NULL.
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: CLDAPConObject ** - ptr to newly created object.
//
//----------------------------------------------------------------------------
HRESULT CLDAPConObject::CreateConnectionObject( CLDAPConObject FAR * FAR * ppConnectionObject, PADSLDP pLdapHandle // defaulted to NULL
) { HRESULT hr = S_OK; CLDAPConObject FAR * pConObj = NULL; CPropertyManager FAR * pIntfPropMgr = NULL;
pConObj = new CLDAPConObject();
if (!pConObj) { RRETURN_EXP_IF_ERR(E_OUTOFMEMORY); }
//
// Add a ref to the ldap handle if one was passed in.
//
if (pLdapHandle) { pConObj->_pLdapHandle = pLdapHandle; pConObj->_fConnected = TRUE; LdapCacheAddRef(pConObj->_pLdapHandle); }
hr = CPropertyManager::CreatePropertyManager( (IUmiConnection *) pConObj, NULL, // outer unk
NULL, // credentials
IntfPropsConnection, &pIntfPropMgr );
BAIL_ON_FAILURE(hr);
pConObj->_pPropMgr = pIntfPropMgr; *ppConnectionObject = pConObj;
RRETURN(S_OK); error:
//
// If we get here, we likely could not create the property manager.
//
if (pConObj) { delete pConObj; }
RRETURN(hr); }
STDMETHODIMP CLDAPConObject::QueryInterface(REFIID iid, LPVOID FAR* ppv) { HRESULT hr = S_OK;
SetLastStatus(0);
if (ppv == NULL) { RRETURN(E_POINTER); }
if (IsEqualIID(iid, IID_IUnknown)){ *ppv = (IUnknown FAR *) this; } else if (IsEqualIID(iid, IID_IUmiPropList)) { *ppv = (IUmiConnection FAR *) this; } else if (IsEqualIID(iid, IID_IUmiBaseObject)) { *ppv = (IUmiConnection FAR *) this; } else if (IsEqualIID(iid, IID_IUmiConnection)) { *ppv = (IUmiConnection FAR *) this; } else { *ppv = NULL; SetLastStatus(E_NOINTERFACE); return E_NOINTERFACE; } AddRef(); return NOERROR; }
//
// IUmiConnection methods.
//
//+---------------------------------------------------------------------------
// Function: CLDAPConObject::Open
//
// Synopsis: Opens a connection to the server (either implicityly
// specified in the url or explicitly in the interface
// properties. If there is already an underlyng ldap connection,
// subsequent open operations will fail if they do not use the same
// underlying connection.
//
// Arguments: pUrl - IUmiUrl object pointing to object to be fetched.
// uFlags - Flags for the operation (currently on 0).
// TargetIID - IID requested on the target object.
// ppvRes - ptr to return the target object.
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: The status of the object and underlying ldap handle ptr.
//
//----------------------------------------------------------------------------
STDMETHODIMP CLDAPConObject::Open( IUmiURL *pURL, ULONG uFlags, REFIID TargetIID, void ** ppvRes ) { HRESULT hr = S_OK; LPWSTR pszUrl = NULL; IUnknown *pUnk = NULL; IADsObjOptPrivate * pPrivOpt = NULL; PADSLDP pLdapTmpHandle = NULL; //
// Default values for credentials.
//
LPWSTR pszUserName = NULL; LPWSTR pszPassword = NULL; LPWSTR pszLdapPath = NULL; DWORD dwFlags = 0; BOOL fFlag; SetLastStatus(0);
if (!ppvRes || !pURL) { BAIL_ON_FAILURE(hr = E_INVALIDARG); } if (uFlags != 0) { BAIL_ON_FAILURE(hr = UMI_E_INVALID_FLAGS); }
*ppvRes = NULL; //
// UrlToLDAPPath can handle both native and umi paths.
//
hr = UrlToLDAPPath( pURL, &pszLdapPath ); BAIL_ON_FAILURE(hr);
//
// Prepare the credentials if applicable.
//
if (!_pCredentials) { //
// Get the params from the property mgr.
//
hr = _pPropMgr->GetStringProperty(L"__UserId", &pszUserName); if (hr == E_OUTOFMEMORY) { BAIL_ON_FAILURE(hr); }
hr = _pPropMgr->GetStringProperty(L"__Password", &pszPassword); if (hr == E_OUTOFMEMORY) { BAIL_ON_FAILURE(hr); }
hr = _pPropMgr->GetBoolProperty( L"__SECURE_AUTHENTICATION", &fFlag ); BAIL_ON_FAILURE(hr);
if (fFlag) { dwFlags |= ADS_SECURE_AUTHENTICATION; }
hr = _pPropMgr->GetBoolProperty( L"__NO_AUTHENTICATION", &fFlag ); BAIL_ON_FAILURE(hr);
if (fFlag) { dwFlags |= ADS_NO_AUTHENTICATION; }
hr = _pPropMgr->GetBoolProperty( L"__PADS_READONLY_SERVER", &fFlag ); BAIL_ON_FAILURE(hr);
if (fFlag) { dwFlags |= ADS_READONLY_SERVER; }
hr = _pPropMgr->GetBoolProperty( L"__PADS_PROMPT_CREDENTIALS", &fFlag ); BAIL_ON_FAILURE(hr);
if (fFlag) { dwFlags |= ADS_PROMPT_CREDENTIALS; }
hr = _pPropMgr->GetBoolProperty( L"__PADS_SERVER_BIND", &fFlag ); BAIL_ON_FAILURE(hr);
if (fFlag) { dwFlags |= ADS_SERVER_BIND; }
hr = _pPropMgr->GetBoolProperty( L"__PADS_FAST_BIND", &fFlag ); BAIL_ON_FAILURE(hr);
if (fFlag) { dwFlags |= ADS_FAST_BIND; }
hr = _pPropMgr->GetBoolProperty( L"__PADS_USE_SIGNING", &fFlag ); BAIL_ON_FAILURE(hr);
if (fFlag) { dwFlags |= ADS_USE_SIGNING; }
hr = _pPropMgr->GetBoolProperty( L"__PADS_USE_SEALING", &fFlag ); BAIL_ON_FAILURE(hr);
if (fFlag) { dwFlags |= ADS_USE_SEALING; }
// hr = _pPropMgr->GetLongProperty(L"__USE_ENCRYPTION", &lVal);
// BAIL_ON_FAILURE(hr);
// Spec needs to be resolved before we can do this.
//
// Always do this as this is what tells us we are in UMI mode.
//
dwFlags |= ADS_AUTH_RESERVED;
_pCredentials = new CCredentials( pszUserName, pszPassword, dwFlags );
if (!_pCredentials) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } } //
// In the future we might want to add some sanity check before
// making this call. That might save some network traffic in the
// rare cases.
// Note that currently, we always get the object and then we compare
// the handles to see if we have inded got an object on the same
// connection (and fail appropriately if not).
//
hr = ::GetObject( pszLdapPath, *_pCredentials, (LPVOID *) &pUnk ) ; BAIL_ON_FAILURE(hr);
//
// By default we get back IADs, so we need to QI for intf.
//
hr = pUnk->QueryInterface(TargetIID, ppvRes); BAIL_ON_FAILURE(hr);
//
// At this point copy over the handle if applicable. If the handle is
// already set, then we need to make sure we are using the same
// connection.
// If do not get the handle for whatever reason, we will use the
// defaulted NULL value and in that case we wont save the handle or
// compare the value.
//
hr = pUnk->QueryInterface(IID_IADsObjOptPrivate, (LPVOID *) &pPrivOpt); if (SUCCEEDED(hr)) { //
// If we succeeded then we want to try and compare handles.
//
hr = pPrivOpt->GetOption( LDP_CACHE_ENTRY, (void*) &pLdapTmpHandle );
}
//
// Reset hr just in case the above failed.
//
hr = S_OK; if (_fConnected) { //
// Verify that the handles are the same.
//
if (_pLdapHandle && pLdapTmpHandle && (_pLdapHandle != pLdapTmpHandle)) { BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER); } } else { //
// New connection.
//
if (pLdapTmpHandle) { _pLdapHandle = pLdapTmpHandle; _fConnected = TRUE; LdapCacheAddRef(_pLdapHandle); } }
error:
//
// Release the ref in all cases. If QI failed that will del the obj.
//
if (pUnk) { pUnk->Release(); }
if (pPrivOpt) { pPrivOpt->Release(); } if (FAILED(hr)) { //
// Update the error status.
//
SetLastStatus(hr);
hr = MapHrToUmiError(hr); if (*ppvRes) { //
// We got the object but a subsequent operation failed.
//
*ppvRes = NULL; pUnk->Release(); } }
if (pszUserName) { FreeADsStr(pszUserName); }
if (pszPassword) { FreeADsStr(pszPassword); } if (pszLdapPath) { FreeADsMem(pszLdapPath); } RRETURN(hr); }
//
// IUmiBaseObject methods.
//
STDMETHODIMP CLDAPConObject::GetLastStatus( ULONG uFlags, ULONG *puSpecificStatus, REFIID riid, LPVOID *pStatusObj ) { if (pStatusObj) { *pStatusObj = NULL; } if (puSpecificStatus) { *puSpecificStatus = 0; } else { RRETURN(E_INVALIDARG); } if (uFlags) { RRETURN(UMI_E_INVALID_FLAGS); } *puSpecificStatus = _ulErrorStatus; RRETURN(S_OK); }
STDMETHODIMP CLDAPConObject::GetInterfacePropList( ULONG uFlags, IUmiPropList **pPropList ) { RRETURN(_pPropMgr->QueryInterface(IID_IUmiPropList, (void **) pPropList)); }
//
// Methods defined on the proplist interface - none are implemented.
// All the properties need to be set on the interface property list.
//
STDMETHODIMP CLDAPConObject::Put( IN LPCWSTR pszName, IN ULONG uFlags, IN UMI_PROPERTY_VALUES *pProp ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CLDAPConObject::Get( IN LPCWSTR pszName, IN ULONG uFlags, OUT UMI_PROPERTY_VALUES **pProp ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CLDAPConObject::GetAt( IN LPCWSTR pszName, IN ULONG uFlags, IN ULONG uBufferLength, OUT LPVOID pExisitingMem ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CLDAPConObject::Delete( IN LPCWSTR pszName, IN ULONG ulFlags ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CLDAPConObject::GetAs( IN LPCWSTR pszName, IN ULONG uFlags, IN ULONG uCoercionType, IN OUT UMI_PROPERTY_VALUES **pProp ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CLDAPConObject::FreeMemory( ULONG uReserved, LPVOID pMem ) { if (pMem) { //
// At this time this has to be a pUmiProperty. Ideally we should
// tag this in some way so that we can check to make sure.
//
RRETURN(FreeUmiPropertyValues((UMI_PROPERTY_VALUES *)pMem)); }
RRETURN(S_OK); }
STDMETHODIMP CLDAPConObject::GetProps( IN LPCWSTR* pszNames, IN ULONG uNameCount, IN ULONG uFlags, OUT UMI_PROPERTY_VALUES **pProps ) { RRETURN(E_NOTIMPL); }
HRESULT CLDAPConObject::PutProps( IN LPCWSTR* pszNames, IN ULONG uNameCount, IN ULONG uFlags, IN UMI_PROPERTY_VALUES *pProps ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CLDAPConObject::PutFrom( IN LPCWSTR pszName, IN ULONG uFlags, IN ULONG uBufferLength, IN LPVOID pExistingMem ) { RRETURN(E_NOTIMPL); }
|