382 lines
9 KiB
C++
382 lines
9 KiB
C++
|
//---------------------------------------------------------------------------
|
||
|
//
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1997
|
||
|
//
|
||
|
// File: cdsobj.cxx
|
||
|
//
|
||
|
// Contents: Microsoft ADs LDAP Provider DSObject
|
||
|
//
|
||
|
//
|
||
|
// History: 02-20-97 yihsins Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
#include "ldap.hxx"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
DWORD
|
||
|
ComputeObjectInfoSize(
|
||
|
PADS_OBJECT_INFO pObjectInfo
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
MarshallObjectInfo(
|
||
|
PADS_OBJECT_INFO pSrcObjectInfo,
|
||
|
LPBYTE pDestObjectInfo,
|
||
|
LPBYTE pEnd
|
||
|
);
|
||
|
|
||
|
LPBYTE
|
||
|
PackStrings(
|
||
|
LPWSTR *pSource,
|
||
|
LPBYTE pDest,
|
||
|
DWORD *DestOffsets,
|
||
|
LPBYTE pEnd
|
||
|
);
|
||
|
|
||
|
HRESULT
|
||
|
CLDAPGenObject::SetObjectAttributes(
|
||
|
PADS_ATTR_INFO pAttributeEntries,
|
||
|
DWORD dwNumAttributes,
|
||
|
DWORD *pdwNumAttributesModified
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
//
|
||
|
// Make sure that the last error is reset
|
||
|
//
|
||
|
Macro_ClearADsLastError(L"LDAP Provider");
|
||
|
|
||
|
hr = ADsSetObjectAttributes( _pLdapHandle,
|
||
|
_pszLDAPServer,
|
||
|
_pszLDAPDn,
|
||
|
_Credentials,
|
||
|
_dwPort,
|
||
|
_seInfo,
|
||
|
pAttributeEntries,
|
||
|
dwNumAttributes,
|
||
|
pdwNumAttributesModified );
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CLDAPGenObject::GetObjectAttributes(
|
||
|
LPWSTR *pAttributeNames,
|
||
|
DWORD dwNumberAttributes,
|
||
|
PADS_ATTR_INFO *ppAttributeEntries,
|
||
|
DWORD * pdwNumAttributesReturned
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
//
|
||
|
// Make sure that the last error is reset
|
||
|
//
|
||
|
Macro_ClearADsLastError(L"LDAP Provider");
|
||
|
|
||
|
hr = ADsGetObjectAttributes( _pLdapHandle,
|
||
|
_pszLDAPServer,
|
||
|
_pszLDAPDn,
|
||
|
_Credentials,
|
||
|
_dwPort,
|
||
|
_seInfo,
|
||
|
pAttributeNames,
|
||
|
dwNumberAttributes,
|
||
|
ppAttributeEntries,
|
||
|
pdwNumAttributesReturned );
|
||
|
|
||
|
RRETURN(hr);
|
||
|
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CLDAPGenObject::CreateDSObject(
|
||
|
LPWSTR pszRDNName,
|
||
|
PADS_ATTR_INFO pAttributeEntries,
|
||
|
DWORD dwNumAttributes,
|
||
|
IDispatch * FAR* ppObject
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
IADs *pADs = NULL;
|
||
|
TCHAR szADsClassName[64];
|
||
|
TCHAR szLDAPClassName[64];
|
||
|
DWORD i;
|
||
|
PADS_ATTR_INFO pThisAttribute;
|
||
|
LDAP_SCHEMA_HANDLE hSchema = NULL;
|
||
|
BOOL fSecDesc = FALSE;
|
||
|
DWORD dwSecDescType = ADSI_LDAPC_SECDESC_NONE;
|
||
|
|
||
|
//
|
||
|
// Make sure that the last error is reset
|
||
|
//
|
||
|
Macro_ClearADsLastError(L"LDAP Provider");
|
||
|
|
||
|
//
|
||
|
// Check and see if security descriptor is one of the attributes.
|
||
|
//
|
||
|
for (i=0; (i < dwNumAttributes) && (fSecDesc == FALSE); i++) {
|
||
|
pThisAttribute = pAttributeEntries + i;
|
||
|
if (_tcsicmp(
|
||
|
pThisAttribute->pszAttrName,
|
||
|
L"ntSecurityDescriptor")
|
||
|
== 0)
|
||
|
{
|
||
|
fSecDesc = TRUE;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
if (fSecDesc) {
|
||
|
//
|
||
|
// Use the create extended method only if the control
|
||
|
// is supported by the server
|
||
|
//
|
||
|
hr = ReadSecurityDescriptorControlType(
|
||
|
_pszLDAPServer,
|
||
|
&dwSecDescType,
|
||
|
_Credentials,
|
||
|
_dwPort
|
||
|
);
|
||
|
|
||
|
if (FAILED(hr) || (dwSecDescType != ADSI_LDAPC_SECDESC_NT)) {
|
||
|
//
|
||
|
// Do not use the control
|
||
|
//
|
||
|
fSecDesc = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Get the LDAP path of the object to create
|
||
|
//
|
||
|
hr = ADsCreateDSObjectExt(
|
||
|
_pLdapHandle,
|
||
|
_ADsPath,
|
||
|
pszRDNName,
|
||
|
pAttributeEntries,
|
||
|
dwNumAttributes,
|
||
|
_seInfo,
|
||
|
fSecDesc
|
||
|
);
|
||
|
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
if (ppObject) {
|
||
|
for (i = 0; i < dwNumAttributes; i++) {
|
||
|
pThisAttribute = pAttributeEntries + i;
|
||
|
if ( _tcsicmp( pThisAttribute->pszAttrName,
|
||
|
TEXT("objectClass")) == 0 ) {
|
||
|
_tcscpy( szLDAPClassName,
|
||
|
(LPTSTR)pThisAttribute->pADsValues->CaseIgnoreString);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
hr = CreateGenericObject(
|
||
|
_ADsPath,
|
||
|
pszRDNName,
|
||
|
szLDAPClassName,
|
||
|
_Credentials,
|
||
|
ADS_OBJECT_BOUND,
|
||
|
IID_IADs,
|
||
|
(void **) &pADs
|
||
|
);
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
hr = pADs->QueryInterface(
|
||
|
IID_IDispatch,
|
||
|
(void **)ppObject
|
||
|
);
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
}
|
||
|
|
||
|
error:
|
||
|
|
||
|
if ( pADs ) {
|
||
|
pADs->Release();
|
||
|
}
|
||
|
|
||
|
if ( hSchema ) {
|
||
|
SchemaClose( &hSchema );
|
||
|
}
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CLDAPGenObject::DeleteDSObject(
|
||
|
LPWSTR pszRDNName
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
//
|
||
|
// Make sure that the last error is reset
|
||
|
//
|
||
|
Macro_ClearADsLastError(L"LDAP Provider");
|
||
|
|
||
|
//
|
||
|
// Get the LDAP path of the object to create
|
||
|
//
|
||
|
hr = ADsDeleteDSObject(
|
||
|
_pLdapHandle,
|
||
|
_ADsPath,
|
||
|
pszRDNName
|
||
|
);
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|
||
|
|
||
|
HRESULT
|
||
|
CLDAPGenObject::GetObjectInformation(
|
||
|
THIS_ PADS_OBJECT_INFO *ppObjInfo
|
||
|
)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
ADS_OBJECT_INFO ObjectInfo;
|
||
|
PADS_OBJECT_INFO pObjectInfo = &ObjectInfo;
|
||
|
LPBYTE pBuffer = NULL;
|
||
|
DWORD dwSize = 0;
|
||
|
BSTR bstrSchema = NULL;
|
||
|
BSTR bstrClass = NULL;
|
||
|
|
||
|
//
|
||
|
// Make sure that the last error is reset
|
||
|
//
|
||
|
Macro_ClearADsLastError(L"LDAP Provider");
|
||
|
|
||
|
hr = get_Schema( &bstrSchema );
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
hr = get_Class( &bstrClass );
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
pObjectInfo->pszRDN = _Name;
|
||
|
pObjectInfo->pszObjectDN = _ADsPath;
|
||
|
pObjectInfo->pszParentDN = _Parent;
|
||
|
pObjectInfo->pszSchemaDN = bstrSchema;
|
||
|
pObjectInfo->pszClassName = bstrClass;
|
||
|
|
||
|
dwSize = ComputeObjectInfoSize(pObjectInfo);
|
||
|
|
||
|
pBuffer = (LPBYTE)AllocADsMem(dwSize);
|
||
|
if (!pBuffer) {
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
}
|
||
|
|
||
|
hr = MarshallObjectInfo(
|
||
|
pObjectInfo,
|
||
|
pBuffer,
|
||
|
pBuffer + dwSize
|
||
|
);
|
||
|
BAIL_ON_FAILURE(hr);
|
||
|
|
||
|
*ppObjInfo = (PADS_OBJECT_INFO) pBuffer;
|
||
|
|
||
|
error:
|
||
|
|
||
|
if ( bstrSchema )
|
||
|
SysFreeString( bstrSchema );
|
||
|
|
||
|
if ( bstrClass )
|
||
|
SysFreeString( bstrClass );
|
||
|
|
||
|
RRETURN(hr);
|
||
|
}
|
||
|
|
||
|
DWORD
|
||
|
ComputeObjectInfoSize(
|
||
|
PADS_OBJECT_INFO pObjectInfo
|
||
|
)
|
||
|
{
|
||
|
DWORD dwLen = 0;
|
||
|
|
||
|
dwLen += (wcslen(pObjectInfo->pszRDN) + 1) * sizeof(WCHAR);
|
||
|
dwLen += (wcslen(pObjectInfo->pszObjectDN) + 1) * sizeof(WCHAR);
|
||
|
dwLen += (wcslen(pObjectInfo->pszParentDN) + 1) * sizeof(WCHAR);
|
||
|
dwLen += (wcslen(pObjectInfo->pszSchemaDN) + 1) * sizeof(WCHAR);
|
||
|
dwLen += (wcslen(pObjectInfo->pszClassName) + 1) * sizeof(WCHAR);
|
||
|
|
||
|
dwLen += sizeof(ADS_OBJECT_INFO);
|
||
|
|
||
|
return(dwLen);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// This assumes that addr is an LPBYTE type.
|
||
|
//
|
||
|
#define WORD_ALIGN_DOWN(addr) \
|
||
|
addr = ((LPBYTE)((DWORD_PTR)addr & ~1))
|
||
|
|
||
|
DWORD ObjectInfoStrings[] = {
|
||
|
FIELD_OFFSET(ADS_OBJECT_INFO, pszRDN),
|
||
|
FIELD_OFFSET(ADS_OBJECT_INFO, pszObjectDN),
|
||
|
FIELD_OFFSET(ADS_OBJECT_INFO, pszParentDN),
|
||
|
FIELD_OFFSET(ADS_OBJECT_INFO, pszSchemaDN),
|
||
|
FIELD_OFFSET(ADS_OBJECT_INFO, pszClassName),
|
||
|
0xFFFFFFFF
|
||
|
};
|
||
|
|
||
|
HRESULT
|
||
|
MarshallObjectInfo(
|
||
|
PADS_OBJECT_INFO pSrcObjectInfo,
|
||
|
LPBYTE pDestObjectInfo,
|
||
|
LPBYTE pEnd
|
||
|
)
|
||
|
{
|
||
|
LPWSTR SourceStrings[sizeof(ADS_OBJECT_INFO)/sizeof(LPWSTR)];
|
||
|
LPWSTR *pSourceStrings=SourceStrings;
|
||
|
|
||
|
memset(SourceStrings, 0, sizeof(ADS_OBJECT_INFO));
|
||
|
*pSourceStrings++ = pSrcObjectInfo->pszRDN;
|
||
|
*pSourceStrings++ = pSrcObjectInfo->pszObjectDN;
|
||
|
*pSourceStrings++ = pSrcObjectInfo->pszParentDN;
|
||
|
*pSourceStrings++ = pSrcObjectInfo->pszSchemaDN;
|
||
|
*pSourceStrings++ = pSrcObjectInfo->pszClassName;
|
||
|
|
||
|
pEnd = PackStrings(
|
||
|
SourceStrings,
|
||
|
pDestObjectInfo,
|
||
|
ObjectInfoStrings,
|
||
|
pEnd
|
||
|
);
|
||
|
|
||
|
RRETURN(S_OK);
|
||
|
}
|
||
|
|
||
|
LPBYTE
|
||
|
PackStrings(
|
||
|
LPWSTR *pSource,
|
||
|
LPBYTE pDest,
|
||
|
DWORD *DestOffsets,
|
||
|
LPBYTE pEnd
|
||
|
)
|
||
|
{
|
||
|
DWORD cbStr;
|
||
|
WORD_ALIGN_DOWN(pEnd);
|
||
|
|
||
|
while (*DestOffsets != -1) {
|
||
|
if (*pSource) {
|
||
|
cbStr = wcslen(*pSource)*sizeof(WCHAR) + sizeof(WCHAR);
|
||
|
pEnd -= cbStr;
|
||
|
CopyMemory( pEnd, *pSource, cbStr);
|
||
|
*(LPWSTR *)(pDest+*DestOffsets) = (LPWSTR)pEnd;
|
||
|
} else {
|
||
|
*(LPWSTR *)(pDest+*DestOffsets)=0;
|
||
|
}
|
||
|
pSource++;
|
||
|
DestOffsets++;
|
||
|
}
|
||
|
return pEnd;
|
||
|
}
|
||
|
|