|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 2000.
//
// File: umi2ldap.cxx
//
// Contents: File containing the implemenation of the conversion routines
// that convert the user given UMI values to ldap values that can
// subsequently be cached if required.
//
// History: 02-17-00 AjayR Created.
//
//----------------------------------------------------------------------------
#include "ldap.hxx"
//+---------------------------------------------------------------------------
// Function: UmiTypeLPWSTRToLdapString
//
// Synopsis: Converts a string value to an equivalent ldap value.
//
// Arguments: Self explanatory
//
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: LDAPOBJECT_STRING(pLdaDestObject)
//
//----------------------------------------------------------------------------
HRESULT UmiTypeLPWSTRToLdapString( LPWSTR pszSourceString, PLDAPOBJECT pLdapDestObject ) { ADsAssert(pszSourceString);
//
// We should not have NULL values but it is a good idea to check.
//
if (pszSourceString) { LDAPOBJECT_STRING(pLdapDestObject) = AllocADsStr(pszSourceString);
if (!LDAPOBJECT_STRING(pLdapDestObject)) { RRETURN(E_OUTOFMEMORY); } }
RRETURN(S_OK); }
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeBoolean
//
// Synopsis: Converts a bool value to an ldap boolean value.
//
// Arguments: Self explanatory
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: LDAPOBJECT_STRING(pLdaDestObject) appropriately.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeBoolean( BOOL fBool, PLDAPOBJECT pLdapDestObject ) { if (fBool) { LDAPOBJECT_STRING(pLdapDestObject) = AllocADsStr(L"TRUE"); } else { LDAPOBJECT_STRING(pLdapDestObject) = AllocADsStr(L"FALSE"); }
if (!LDAPOBJECT_STRING(pLdapDestObject)) { RRETURN(E_OUTOFMEMORY); }
RRETURN(S_OK); }
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeCopyI4
//
// Synopsis: Converts a long (I4) value to an equivalent ldap value.
//
// Arguments: Self explanatory
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: LDAPOBJECT_STRING(pLdaDestObject) contains the new values.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeCopyI4( LONG lVal, PLDAPOBJECT pLdapDestObject ) { HRESULT hr = S_OK; TCHAR Buffer[64];
ADsAssert(pLdapDestObject);
_ltot(lVal, Buffer, 10);
LDAPOBJECT_STRING(pLdapDestObject) = AllocADsStr(Buffer); if (!LDAPOBJECT_STRING(pLdapDestObject)) { hr = E_OUTOFMEMORY; }
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeOctetString
//
// Synopsis: Converts an UmiOctetString to an ldap ber value.
//
// Arguments: Self explanatory
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: pLdapDestObject is updated suitably with the ber value.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeOctetString( UMI_OCTET_STRING umiOctetStr, PLDAPOBJECT pLdapDestObject ) { DWORD dwLength = 0;
if (umiOctetStr.lpValue) { dwLength = umiOctetStr.uLength;
LDAPOBJECT_BERVAL(pLdapDestObject) = (struct berval *) AllocADsMem(dwLength + sizeof(struct berval));
if (!LDAPOBJECT_BERVAL(pLdapDestObject)) { RRETURN(E_OUTOFMEMORY); }
//
// Set the pointer to data and the length in the dest object.
//
LDAPOBJECT_BERVAL_LEN(pLdapDestObject) = dwLength; LDAPOBJECT_BERVAL_VAL(pLdapDestObject) = (CHAR *) ( (LPBYTE) LDAPOBJECT_BERVAL(pLdapDestObject) + sizeof(struct berval)); memcpy( LDAPOBJECT_BERVAL_VAL(pLdapDestObject), umiOctetStr.lpValue, dwLength ); } // umiOctetStr.lpValue
RRETURN(S_OK);
}
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeSecurityDescriptor.
//
// Synopsis: Converts a UmiComObject that is an SD to an equivalent
// ldap binary blob.
//
// Arguments: umiComObject - Has the IADsSecDesc to convert.
// pLdapDestObjects - Return value of encoded ldap data.
// pCreds - Credentials to use for conversion.
// pszServerName - ServerName associated with SD.
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: pLdapDestObject is updated suitably with the ber value.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeCopySecurityDescriptor( UMI_COM_OBJECT umiComObject, PLDAPOBJECT pLdapDestObject, CCredentials *pCreds, LPWSTR pszServerName ) { HRESULT hr = S_OK; PSECURITY_DESCRIPTOR pBinarySecDesc = NULL; IUnknown *pUnk = (IUnknown *) umiComObject.pInterface; IADsSecurityDescriptor* pADsSecDesc = NULL; CCredentials creds; DWORD dwSDLength = 0;
//
// QI for the IADsSecDesc, that way we can be sure of the interface.
//
hr = pUnk->QueryInterface( IID_IADsSecurityDescriptor, (void **) &pADsSecDesc ); BAIL_ON_FAILURE(hr); //
// Update the credentials if needed.
//
if (pCreds) { creds = *pCreds; }
//
// Call the helper that does the conversion in activeds.dll
//
hr = ConvertSecurityDescriptorToSecDes( pszServerName, creds, pADsSecDesc, &pBinarySecDesc, &dwSDLength, TRUE // NT style SD.
); BAIL_ON_FAILURE(hr);
//
// Now we need to copy over the data into the ldap struct.
//
LDAPOBJECT_BERVAL(pLdapDestObject) = (struct berval *) AllocADsMem( sizeof(struct berval) + dwSDLength);
if ( LDAPOBJECT_BERVAL(pLdapDestObject) == NULL) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); }
LDAPOBJECT_BERVAL_LEN(pLdapDestObject) = dwSDLength; LDAPOBJECT_BERVAL_VAL(pLdapDestObject) = (CHAR *) ((LPBYTE) LDAPOBJECT_BERVAL(pLdapDestObject) + sizeof(struct berval));
memcpy( LDAPOBJECT_BERVAL_VAL(pLdapDestObject), pBinarySecDesc, dwSDLength );
error:
if (pBinarySecDesc) { FreeADsMem(pBinarySecDesc); }
if (pADsSecDesc) { pADsSecDesc->Release(); }
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeCopyDNWithBinary.
//
// Synopsis: Converts a UmiComObject that is DNWithBinary obj to
// and equivalent ldap data.
//
// Arguments: umiComObject - Has the IADsDNWithBinary to convert.
// pLdapDestObjects - Return value of encoded ldap data.
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: pLdapDestObject is updated suitably with the ber value.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeCopyDNWithBinary( UMI_COM_OBJECT umiComObject, PLDAPOBJECT pLdapDestObject ) { HRESULT hr = S_OK; IUnknown * pUnk = (IUnknown *)umiComObject.pInterface; VARIANT vVar;
VariantInit(&vVar);
vVar.vt = VT_DISPATCH;
hr = pUnk->QueryInterface(IID_IDispatch, (void **) &vVar.pdispVal); BAIL_ON_FAILURE(hr);
//
// Call the var2ldap conversion helper to do all the hard work !.
//
hr = VarTypeToLdapTypeDNWithBinary( &vVar, pLdapDestObject );
error:
VariantClear(&vVar);
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeCopyDNWithString.
//
// Synopsis: Converts a UmiComObject that is DNWithString obj to
// and equivalent ldap data.
//
// Arguments: umiComObject - Has the IADsDNWithString to convert.
// pLdapDestObjects - Return value of encoded ldap data.
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: pLdapDestObject is updated suitably with the ber value.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeCopyDNWithString( UMI_COM_OBJECT umiComObject, PLDAPOBJECT pLdapDestObject ) { HRESULT hr = S_OK; IUnknown * pUnk = (IUnknown *)umiComObject.pInterface; VARIANT vVar;
VariantInit(&vVar);
vVar.vt = VT_DISPATCH;
hr = pUnk->QueryInterface(IID_IDispatch, (void **) &vVar.pdispVal); BAIL_ON_FAILURE(hr);
//
// Call the var2ldap conversion helper to do all the hard work !.
//
hr = VarTypeToLdapTypeDNWithString( &vVar, pLdapDestObject );
error:
VariantClear(&vVar);
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeCopyI8
//
// Synopsis: Convert an int64 value to the corresponding ldap value.
//
// Arguments: Self explanatory
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: pLdapDestObject contains the encoded large integer object.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeCopyI8( __int64 int64Val, PLDAPOBJECT pLdapDestObject ) { HRESULT hr = S_OK; TCHAR Buffer[64];
if (!swprintf (Buffer, L"%I64d", int64Val)) BAIL_ON_FAILURE(hr = E_ADS_CANT_CONVERT_DATATYPE);
LDAPOBJECT_STRING(pLdapDestObject) = /*(LPTSTR)*/ AllocADsStr( Buffer );
if (!LDAPOBJECT_STRING(pLdapDestObject)) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); }
error :
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeCopyUTCTime
//
// Synopsis: Convert a SYSTEMTIME object to the corresponding ldap value.
//
// Arguments: Self explanatory
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: pLdapDestObject contains the encoded utc time value.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeCopyUTCTime( SYSTEMTIME sysTimeObj, PLDAPOBJECT pLdapDestObject ) { HRESULT hr; DWORD dwSyntaxId; ADSVALUE adsValue;
adsValue.dwType = ADSTYPE_UTC_TIME; adsValue.UTCTime = sysTimeObj;
//
// Use the helper to convert the value appropriately.
//
hr = AdsTypeToLdapTypeCopyTime( &adsValue, pLdapDestObject, &dwSyntaxId );
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeCopyGeneralizedTime
//
// Synopsis: Converts a SystemTime value to a ldap generalized time value.
//
// Arguments: Self explanatory
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: pLdapDestObject contains the encoded generalized time value.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeCopyGeneralizedTime( SYSTEMTIME sysTimeObj, PLDAPOBJECT pLdapDestObject ) { HRESULT hr; DWORD dwSyntaxId; ADSVALUE adsValue;
adsValue.dwType = ADSTYPE_UTC_TIME; adsValue.UTCTime = sysTimeObj;
//
// Use the helper to convert the value appropriately.
//
hr = AdsTypeToLdapTypeCopyGeneralizedTime( &adsValue, pLdapDestObject, &dwSyntaxId );
RRETURN(hr); }
//+---------------------------------------------------------------------------
// Function: UmiTypeEnumToLdapTypeEnum
//
// Synopsis: Converts the passed in umiType to the equivalent ldapType.
// Note that the conversion is just for the type and not the actual
// data itself. Example UMI_TYPE_I4 to LDAPTYPE_INTEGER.
//
// Arguments: ulUmiType - Umi type to convert.
// pdwSyntax - Return ldap syntax.
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: *pdwSyntax with appropriate value.
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeEnum( ULONG ulUmiType, PDWORD pdwSyntax ) { HRESULT hr = S_OK;
switch (ulUmiType) { case UMI_TYPE_I4 : *pdwSyntax = LDAPTYPE_INTEGER; break;
case UMI_TYPE_I8 : *pdwSyntax = LDAPTYPE_INTEGER8; break;
case UMI_TYPE_SYSTEMTIME : //
// What about utc Time ?
//
*pdwSyntax = LDAPTYPE_GENERALIZEDTIME; break;
case UMI_TYPE_BOOL : *pdwSyntax = LDAPTYPE_BOOLEAN; break;
case UMI_TYPE_IUNKNOWN : //
// How about the other IUnknowns ?
//
*pdwSyntax = LDAPTYPE_SECURITY_DESCRIPTOR; break;
case UMI_TYPE_LPWSTR : *pdwSyntax = LDAPTYPE_CASEIGNORESTRING; break;
case UMI_TYPE_OCTETSTRING : *pdwSyntax = LDAPTYPE_OCTETSTRING; break;
case UMI_TYPE_UNDEFINED: case UMI_TYPE_NULL : case UMI_TYPE_I1 : case UMI_TYPE_I2 : case UMI_TYPE_UI1 : case UMI_TYPE_UI2 : case UMI_TYPE_UI4 : case UMI_TYPE_UI8 : case UMI_TYPE_R4 : case UMI_TYPE_R8 : case UMI_TYPE_FILETIME : case UMI_TYPE_IDISPATCH : case UMI_TYPE_VARIANT : case UMI_TYPE_UMIARRAY : case UMI_TYPE_DISCOVERY : case UMI_TYPE_DEFAULT : default: *pdwSyntax = (DWORD) -1; hr = E_FAIL; break; }
RRETURN(hr);
}
//+---------------------------------------------------------------------------
// Function: UmiTypeToLdapTypeCopy
//
// Synopsis: Helper routine to convert ldap values to the required UMI
// data type.
//
// Arguments: umiPropArray - input UMI data.
// ulFlags - flags indicating type of operation.
// pLdapDestObjects - Ptr to hold the output from routine.
// dwLdapSyntaxId - ref to dword.
// fUtcTime - optional defaulted to False.
//
// Returns: HRESULT - S_OK or any failure error code.
//
// Modifies: pLdapDestObjects to point to valid data.
// dwLdapSyntaxId with the ldap syntax id for the data type (this
// will enable us to return the data correctly to the user).
//
//----------------------------------------------------------------------------
HRESULT UmiTypeToLdapTypeCopy( UMI_PROPERTY_VALUES umiPropArray, ULONG ulFlags, LDAPOBJECTARRAY *pLdapDestObjects, DWORD &dwLdapSyntaxId, CCredentials *pCreds, LPWSTR pszServerName, BOOL fUtcTime ) { HRESULT hr = S_OK; ULONG ulUmiType, ulCount, ulCtr; PUMI_PROPERTY pUmiProp;
//
// Internal routine so an assert should be enough.
//
ADsAssert(pLdapDestObjects);
//
// Initalize count on ldapobjects to zero and
// default is string values for the contents.
//
pLdapDestObjects->dwCount = 0; pLdapDestObjects->fIsString = TRUE;
//
// Verify that we have some valid data.
//
if (!umiPropArray.pPropArray || (umiPropArray.uCount != 1)) { BAIL_ON_FAILURE(hr = E_INVALIDARG); } pUmiProp = umiPropArray.pPropArray; ulUmiType = pUmiProp->uType; ulCount = pUmiProp->uCount;
if ( ulCount == 0 ) { pLdapDestObjects->dwCount = 0; pLdapDestObjects->pLdapObjects = NULL; RRETURN(S_OK); }
pLdapDestObjects->pLdapObjects = (PLDAPOBJECT)AllocADsMem( ulCount * sizeof(LDAPOBJECT));
if (pLdapDestObjects->pLdapObjects == NULL) RRETURN(E_OUTOFMEMORY);
//
// If we are here, then pUmiValue has to be valid.
//
if (!pUmiProp->pUmiValue) { BAIL_ON_FAILURE(hr = E_INVALIDARG); }
for (ulCtr =0; ulCtr < ulCount; ulCtr++) { //
// Need to go through and convert each of the values.
//
switch (ulUmiType) { //
// Call appropriate routine based on type.
//
case UMI_TYPE_I1 : case UMI_TYPE_I2 :
hr = E_ADS_CANT_CONVERT_DATATYPE; break;
case UMI_TYPE_I4 :
if (!pUmiProp->pUmiValue->lValue) { BAIL_ON_FAILURE(hr = E_INVALIDARG); }
hr = UmiTypeToLdapTypeCopyI4( pUmiProp->pUmiValue->lValue[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr ); dwLdapSyntaxId = LDAPTYPE_INTEGER; break; case UMI_TYPE_I8 :
if (!pUmiProp->pUmiValue->nValue64) { BAIL_ON_FAILURE(hr = E_INVALIDARG); } hr = UmiTypeToLdapTypeCopyI8( pUmiProp->pUmiValue->nValue64[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr ); dwLdapSyntaxId = LDAPTYPE_INTEGER8; break;
case UMI_TYPE_UI1 : case UMI_TYPE_UI2 : case UMI_TYPE_UI4 : case UMI_TYPE_UI8 : case UMI_TYPE_R4 : case UMI_TYPE_R8 : //
// We do not handle any of the unsigned data types or
// the real data types..
//
hr = E_ADS_CANT_CONVERT_DATATYPE; break;
case UMI_TYPE_SYSTEMTIME :
if (!pUmiProp->pUmiValue->sysTimeValue) { BAIL_ON_FAILURE(hr = E_INVALIDARG); } //
// Need to use the special info to see if this is an UTC Time
// value or if this is a Generalized time value - GenTime is
// always the default value though.
//
if (fUtcTime) { hr = UmiTypeToLdapTypeCopyUTCTime( pUmiProp->pUmiValue->sysTimeValue[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr ); dwLdapSyntaxId = LDAPTYPE_UTCTIME; } else { hr = UmiTypeToLdapTypeCopyGeneralizedTime( pUmiProp->pUmiValue->sysTimeValue[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr ); dwLdapSyntaxId = LDAPTYPE_GENERALIZEDTIME; } break;
case UMI_TYPE_BOOL :
if (!pUmiProp->pUmiValue->bValue) { BAIL_ON_FAILURE(hr = E_INVALIDARG); }
hr = UmiTypeToLdapTypeBoolean( pUmiProp->pUmiValue->bValue[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr ); dwLdapSyntaxId = LDAPTYPE_BOOLEAN; break;
case UMI_TYPE_IDISPATCH : case UMI_TYPE_VARIANT : //
// We do not support these.
//
hr = E_ADS_CANT_CONVERT_DATATYPE; break;
case UMI_TYPE_LPWSTR :
if (!pUmiProp->pUmiValue->pszStrValue) { BAIL_ON_FAILURE(hr = E_INVALIDARG); } hr = UmiTypeLPWSTRToLdapString( pUmiProp->pUmiValue->pszStrValue[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr ); dwLdapSyntaxId = LDAPTYPE_CASEEXACTSTRING; break;
case UMI_TYPE_OCTETSTRING : if (!pUmiProp->pUmiValue->octetStr) { BAIL_ON_FAILURE(hr = E_INVALIDARG); } //
// Override default settings as this is no longer true.
//
pLdapDestObjects->fIsString = FALSE;
hr = UmiTypeToLdapTypeOctetString( pUmiProp->pUmiValue->octetStr[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr ); dwLdapSyntaxId = LDAPTYPE_OCTETSTRING; break;
case UMI_TYPE_IUNKNOWN:
if (!pUmiProp->pUmiValue->comObject || !pUmiProp->pUmiValue->comObject[ulCtr].pInterface ) { BAIL_ON_FAILURE(hr = E_INVALIDARG); }
//
// Based on the type we should call the appropriate function.
//
IID *priid; priid = pUmiProp->pUmiValue->comObject[ulCtr].priid;
if (!priid) { BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER); }
if (*priid == IID_IADsSecurityDescriptor) { //
// SD is stored as berval in cache.
//
pLdapDestObjects->fIsString = FALSE; //
// SD needs the servername and credentials for conversion.
//
hr = UmiTypeToLdapTypeCopySecurityDescriptor( pUmiProp->pUmiValue->comObject[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr, pCreds, pszServerName ); dwLdapSyntaxId = LDAPTYPE_SECURITY_DESCRIPTOR; } else if (*priid == IID_IADsDNWithBinary) { //
// Convert DNBin obj to ldap equivalent.
//
hr = UmiTypeToLdapTypeCopyDNWithBinary( pUmiProp->pUmiValue->comObject[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr ); dwLdapSyntaxId = LDAPTYPE_DNWITHBINARY; } else if (*priid == IID_IADsDNWithString) { //
// Convert DNStr obj to ldap equivalent.
//
hr = UmiTypeToLdapTypeCopyDNWithString( pUmiProp->pUmiValue->comObject[ulCtr], pLdapDestObjects->pLdapObjects + ulCtr ); dwLdapSyntaxId = LDAPTYPE_DNWITHSTRING; } else { //
// Unknown type.
//
BAIL_ON_FAILURE(hr = E_ADS_BAD_PARAMETER); } break;
case UMI_TYPE_UMIARRAY : case UMI_TYPE_DISCOVERY : case UMI_TYPE_UNDEFINED : case UMI_TYPE_DEFAULT : hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER); break;
default : hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER); break;
} // end of case statement
//
// if hr is set there was a problem converting value.
//
BAIL_ON_FAILURE(hr); //
// In case of failure we now have one more object to free
// in the ldap object array.
//
pLdapDestObjects->dwCount++;
} // end of for statement
BAIL_ON_FAILURE(hr);
RRETURN(hr);
error:
//
// Free the ldapProperty array as needed.
//
LdapTypeFreeLdapObjects(pLdapDestObjects);
RRETURN(hr); }
|