|
|
#include "ldap.hxx"
#pragma hdrstop
HRESULT CopyObject( IN LPWSTR pszSrcADsPath, IN LPWSTR pszDestContainer, IN ADS_LDP *ldDest, // LDAP handle of destination container
IN SCHEMAINFO * pSchemaInfo, // SCHEMAINFO for the dest container
IN LPWSTR pszCommonName, // optional
OUT IUnknown ** ppObject )
{
HRESULT hr = S_OK; WCHAR szLDAPSrcPath[MAX_PATH]; WCHAR szLDAPDestContainer[MAX_PATH]; ADS_LDP *ldapSrc = NULL, *ldapDest = NULL; LDAPMessage *ldpSrcMsg =NULL; SCHEMAINFO *pDestSchemaInfo = NULL; WCHAR **avalues; DWORD nCount, nNumberOfEntries; WCHAR szADsClass[MAX_PATH]; WCHAR szName[MAX_PATH]; WCHAR szParent[MAX_PATH]; LPWSTR pszRelativeName = NULL;
hr = BuildADsParentPath( pszSrcADsPath, szParent, szName ); BAIL_ON_FAILURE(hr);
hr = GetInfoFromSrcObject( pszSrcADsPath, szLDAPSrcPath, &ldapSrc, &ldpSrcMsg, &avalues, &nCount );
BAIL_ON_FAILURE(hr);
if(ldDest){ ldapDest = ldDest; }
if(pSchemaInfo){ pDestSchemaInfo = pSchemaInfo; }
hr = CreateDestObjectCopy( pszDestContainer, avalues, nCount, ldapSrc, &ldapDest, ldpSrcMsg, &pDestSchemaInfo, pszCommonName, szLDAPDestContainer );
BAIL_ON_FAILURE(hr);
if (pszCommonName){ pszRelativeName = pszCommonName; } else { pszRelativeName = szName; }
hr = InstantiateCopiedObject( pszDestContainer, avalues, nCount, pszRelativeName, ppObject );
error:
if (!pSchemaInfo && pDestSchemaInfo){ pDestSchemaInfo ->Release(); }
if (!ldDest && ldapDest) { LdapCloseObject(ldapDest); ldapDest = NULL; }
if (ldapSrc) { LdapCloseObject(ldapSrc); ldapSrc = NULL; }
if(avalues){ LdapValueFree(avalues); }
if(ldpSrcMsg){ LdapMsgFree( ldpSrcMsg); }
RRETURN(hr);
}
HRESULT GetInfoFromSrcObject( IN LPWSTR pszSrcADsPath, OUT LPWSTR szLDAPSrcPath, OUT ADS_LDP ** pldapSrc, OUT LDAPMessage **pldpSrcMsg, OUT WCHAR ***pavalues, OUT DWORD *pnCount )
{ ADS_LDP *ldapSrc = NULL; LDAPMessage *ldpSrcMsg =NULL; WCHAR **avalues; DWORD nCount, nNumberOfEntries; HRESULT hr = S_OK;
OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = BuildLDAPPathFromADsPath( pszSrcADsPath, szLDAPSrcPath );
BAIL_ON_FAILURE(hr);
hr = LdapOpenObject( szLDAPSrcPath, &ldapSrc );
BAIL_ON_FAILURE(hr);
hr = LdapSearchS( ldapSrc, GET_LDAPDN_FROM_PATH(szLDAPSrcPath), LDAP_SCOPE_BASE, TEXT("(objectClass=*)"), NULL, 0, &ldpSrcMsg );
BAIL_ON_FAILURE(hr);
//
// get the object class of the source object. We need to do this so
// that we can use the information so obtained to test whether there
// is the same object class in the destination location
//
hr = ADsObject(pszSrcADsPath, pObjectInfo); BAIL_ON_FAILURE(hr);
hr = LdapReadAttribute( szLDAPSrcPath, TEXT("objectClass"), &avalues, (int *)&nCount, &ldapSrc, pObjectInfo->PortNumber );
BAIL_ON_FAILURE(hr); if ( nCount == 0 ){
// This object exists but does not have an objectClass. We
// can't do anything without the objectClass. Hence, return
// bad path error.
hr = E_ADS_BAD_PATHNAME; BAIL_ON_FAILURE(hr); }
//
// we have succeeded in getting all the information from the source
// object. We need to validate to see if there is such an object in
// in the destination.
*pldapSrc = ldapSrc; *pldpSrcMsg = ldpSrcMsg; *pavalues = avalues; *pnCount = nCount;
error:
FreeObjectInfo(pObjectInfo); RRETURN(hr);
}
HRESULT CreateDestObjectCopy( IN LPWSTR pszDestContainer, IN WCHAR **avalues, IN DWORD nCount, IN ADS_LDP *ldapSrc, IN OUT ADS_LDP **pldDest, IN LDAPMessage *ldpSrcMsg, IN OUT SCHEMAINFO **ppSchemaInfo, IN LPWSTR pszCommonName, OUT LPWSTR szLDAPDestContainer )
{ ADS_LDP *ldapDest = NULL; LDAPModW *aModsBuffer = NULL; LDAPMessage *ldpAttrMsg = NULL; SCHEMAINFO *pDestSchemaInfo = NULL; DWORD nNumberOfEntries; HRESULT hr = S_OK; DWORD index = 0, dwCount = 0,nNumberOfValues, dwSyntax; VOID *ptr; LPWSTR pszAttrName = NULL; DWORD i= 0, j=0; PLDAPOBJECT *ppaValues = NULL; PLDAPOBJECT paObjClass = NULL;
OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = BuildLDAPPathFromADsPath( pszDestContainer, szLDAPDestContainer ); BAIL_ON_FAILURE(hr);
if (*pldDest){ ldapDest = *pldDest;
} else {
hr = LdapOpenObject( szLDAPDestContainer, &ldapDest );
BAIL_ON_FAILURE(hr);
*pldDest = ldapDest; }
if(*ppSchemaInfo){ pDestSchemaInfo = *ppSchemaInfo; } else {
hr = ADsObject(pszDestContainer, pObjectInfo); BAIL_ON_FAILURE(hr); hr = LdapGetSchema( szLDAPDestContainer, ldapDest, &pDestSchemaInfo, pObjectInfo->PortNumber ); BAIL_ON_FAILURE(hr); *ppSchemaInfo = pDestSchemaInfo; } //
// check to see if the object class of source exists in the naming
// context of the destination
//
/*
index = FindEntryInSearchTable( avalues[nCount -1], pDestSchemaInfo->aClassesSearchTable, 2 * pDestSchemaInfo->nNumOfClasses );
if ( index == -1 ) {
// Cannot find the class name
hr = E_ADS_BAD_PARAMETER; BAIL_ON_FAILURE(hr); }
*/
//
// Now we need to find the number of entries in the ldap message
//
hr = LdapFirstEntry( ldapSrc, ldpSrcMsg, &ldpAttrMsg );
BAIL_ON_FAILURE(hr);
dwCount = 0; hr = LdapFirstAttribute(ldapSrc, ldpAttrMsg, &ptr, &pszAttrName);
BAIL_ON_FAILURE(hr); do { dwCount++; hr = LdapNextAttribute( ldapSrc, ldpAttrMsg, ptr, &pszAttrName );
if (pszAttrName) { FreeADsMem(pszAttrName); } if (FAILED(hr)){ break; }
} while(pszAttrName != NULL);
aModsBuffer = (LDAPModW *) AllocADsMem((dwCount +1) * sizeof(LDAPModW ));
if ( aModsBuffer == NULL ) {
hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
//
// memory has been allocated. we now need to scan the list again
// and copy the entries from the LDAPMessage structure to the
// LDAPModW structure
//
ppaValues= (PLDAPOBJECT *)AllocADsMem(dwCount * sizeof(PLDAPOBJECT));
if (!ppaValues){ hr = E_OUTOFMEMORY; goto error; }
paObjClass = (PLDAPOBJECT)AllocADsMem(sizeof(LDAPOBJECT));
if (!ppaValues){ hr = E_OUTOFMEMORY; goto error; }
hr = LdapFirstAttribute(ldapSrc, ldpAttrMsg, &ptr, &pszAttrName);
BAIL_ON_FAILURE(hr); i=0; j = 0;
do {
hr = LdapGetValuesLen( ldapSrc, ldpAttrMsg, pszAttrName, &ppaValues[j], (int *)&nNumberOfValues );
BAIL_ON_FAILURE(hr);
dwSyntax = GetSyntaxOfAttribute( pszAttrName, pDestSchemaInfo ); if (dwSyntax != LDAPTYPE_UNKNOWN ){
if (wcscmp(pszAttrName, TEXT("distinguishedName"))== 0){ hr = LdapNextAttribute( ldapSrc, ldpAttrMsg, ptr, &pszAttrName ); if (FAILED(hr)){ break; } j++; continue; }
if (wcscmp(pszAttrName, TEXT("objectClass"))== 0){ VARIANT v; V_VT(&v)= VT_BSTR; V_BSTR(&v)= avalues[nCount-1];
hr = VarTypeToLdapTypeString( &v, paObjClass); BAIL_ON_FAILURE(hr);
aModsBuffer[i].mod_bvalues = paObjClass; aModsBuffer[i].mod_op = LDAP_MOD_BVALUES | LDAP_MOD_ADD;
} else {
aModsBuffer[i].mod_type = pszAttrName; aModsBuffer[i].mod_bvalues = ppaValues[j]; aModsBuffer[i].mod_op = LDAP_MOD_BVALUES | LDAP_MOD_ADD; }
i++;
} FreeADsMem( pszAttrName );
hr = LdapNextAttribute( ldapSrc, ldpAttrMsg, ptr, &pszAttrName ); if (FAILED(hr)){ break; } j++;
} while(pszAttrName != NULL);
hr = LdapAddS( ldapDest, GET_LDAPDN_FROM_PATH(szLDAPDestContainer), &aModsBuffer );
BAIL_ON_FAILURE(hr);
error:
FreeObjectInfo(pObjectInfo);
for(j=0; j< dwCount; j++){ if(ppaValues[j]){ LdapValueFreeLen(ppaValues[j]); } }
if(ldpAttrMsg){ LdapMsgFree( ldpAttrMsg); }
if(aModsBuffer){ FreeADsMem(aModsBuffer); }
if (pszAttrName) { FreeADsMem(pszAttrName); } if(ppaValues){ FreeADsMem(ppaValues); }
if(paObjClass){ FreeADsMem(paObjClass); }
RRETURN(hr);
}
HRESULT InstantiateCopiedObject( IN LPWSTR pszDestContainer, IN WCHAR ** avalues, IN DWORD nCount, IN LPWSTR pszRelativeName, OUT IUnknown ** ppObject ) { HRESULT hr = S_OK; IADs *pADs = NULL; WCHAR szADsClassName[MAX_PATH];
MapLdapClassToADsClass( avalues, nCount, szADsClassName );
hr = CLDAPGenObject::CreateGenericObject( pszDestContainer, pszRelativeName, szADsClassName, avalues[nCount-1], ADS_OBJECT_BOUND, IID_IADs, (void **) &pADs ); BAIL_ON_FAILURE(hr);
//
// InstantiateDerivedObject should add-ref this pointer for us.
//
hr = InstantiateDerivedObject( pADs, szADsClassName, IID_IUnknown, (void **)ppObject );
if (FAILED(hr)) {
hr = pADs->QueryInterface( IID_IUnknown, (void **)ppObject ); BAIL_ON_FAILURE(hr); }
error: if(pADs){ pADs->Release(); } RRETURN(hr); }
|