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.
440 lines
11 KiB
440 lines
11 KiB
//---------------------------------------------------------------------------
|
|
//
|
|
//
|
|
// 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");
|
|
|
|
// parameter validation
|
|
if(!pdwNumAttributesModified || !dwNumAttributes)
|
|
{
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
return hr;
|
|
}
|
|
|
|
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");
|
|
|
|
// parameter validation
|
|
// -1 means that return all the attributes.
|
|
|
|
if(!ppAttributeEntries || !pdwNumAttributesReturned)
|
|
{
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
return hr;
|
|
}
|
|
|
|
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* pszLDAPClassName = NULL;
|
|
DWORD i;
|
|
PADS_ATTR_INFO pThisAttribute = NULL;
|
|
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");
|
|
|
|
// parameter validation
|
|
if(!pszRDNName || !ppObject || !dwNumAttributes)
|
|
{
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// Check and see if security descriptor is one of the attributes.
|
|
//
|
|
for (i=0; (i < dwNumAttributes) && (fSecDesc == FALSE); i++) {
|
|
pThisAttribute = pAttributeEntries + i;
|
|
|
|
if(!pThisAttribute)
|
|
{
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
return hr;
|
|
}
|
|
|
|
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 ) {
|
|
|
|
pszLDAPClassName = new TCHAR[_tcslen(pThisAttribute->pADsValues->CaseIgnoreString) + 1];
|
|
if(!pszLDAPClassName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
BAIL_ON_FAILURE(hr);
|
|
}
|
|
|
|
_tcscpy( pszLDAPClassName,
|
|
(LPTSTR)pThisAttribute->pADsValues->CaseIgnoreString);
|
|
break;
|
|
}
|
|
}
|
|
|
|
hr = CreateGenericObject(
|
|
_ADsPath,
|
|
pszRDNName,
|
|
pszLDAPClassName,
|
|
_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 );
|
|
}
|
|
|
|
if(pszLDAPClassName)
|
|
{
|
|
delete [] pszLDAPClassName;
|
|
pszLDAPClassName = NULL;
|
|
}
|
|
|
|
|
|
|
|
RRETURN(hr);
|
|
}
|
|
|
|
HRESULT
|
|
CLDAPGenObject::DeleteDSObject(
|
|
LPWSTR pszRDNName
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Make sure that the last error is reset
|
|
//
|
|
Macro_ClearADsLastError(L"LDAP Provider");
|
|
|
|
// parameter validation
|
|
if(!pszRDNName)
|
|
{
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// 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");
|
|
|
|
// parameter validation
|
|
if(!ppObjInfo)
|
|
{
|
|
hr = E_ADS_BAD_PARAMETER;
|
|
return hr;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|