#include <stdio.h>
#include <string.h> //used for strcpy, etc.
#include <stdlib.h> //used for malloc
#include <ctype.h> //use for isprint
#include <Security/Authorization.h>
#include <DirectoryService/DirServices.h>
#include <DirectoryService/DirServicesUtils.h>
#include <DirectoryService/DirServicesConst.h>
#include "CLDAPPlugIn.h"
#include <DirectoryServiceCore/ServerModuleLib.h>
#include <DirectoryServiceCore/CRCCalc.h>
#include <DirectoryServiceCore/CPlugInRef.h>
#include <DirectoryServiceCore/CContinue.h>
#include <DirectoryServiceCore/DSCThread.h>
#include <DirectoryServiceCore/DSEventSemaphore.h>
#include <DirectoryServiceCore/DSMutexSemaphore.h>
#include <DirectoryServiceCore/CSharedData.h>
#include <DirectoryServiceCore/DSUtils.h>
CContinue *gContinueTable = nil; CPlugInRef *gRefTable = nil;
CPlugInRef *gConfigTable = nil;
uInt32 gConfigTableLen = 0;
static DSEventSemaphore *gKickSearchRequests = nil;
static DSMutexSemaphore *gLDAPOpenMutex = nil;
static const uInt32 kBuffPad = 16;
extern "C" {
CFUUIDRef ModuleFactoryUUID = CFUUIDGetConstantUUIDWithBytes ( NULL, \
0xD9, 0x70, 0xD5, 0x2E, 0xD5, 0x15, 0x11, 0xD3, \
0x9F, 0xF9, 0x00, 0x05, 0x02, 0xC1, 0xC7, 0x36 );
}
static CDSServerModule* _Creator ( void )
{
return( new CLDAPPlugIn );
}
CDSServerModule::tCreator CDSServerModule::sCreator = _Creator;
CLDAPPlugIn::CLDAPPlugIn ( void )
{
fState = kUnknownState;
if ( gLDAPOpenMutex == nil )
{
gLDAPOpenMutex = new DSMutexSemaphore();
}
if ( gContinueTable == nil )
{
gContinueTable = new CContinue( nil );
}
if ( gConfigTable == nil )
{
gConfigTable = new CPlugInRef( nil );
if ( gConfigTable == nil ) throw( (sInt32)eMemoryAllocError );
}
if ( gRefTable == nil )
{
gRefTable = new CPlugInRef( CLDAPPlugIn::ContextDeallocProc );
if ( gRefTable == nil ) throw( (sInt32)eMemoryAllocError );
}
if ( gKickSearchRequests == nil )
{
gKickSearchRequests = new DSEventSemaphore();
if ( gKickSearchRequests == nil ) throw( (sInt32)eMemoryAllocError );
}
pConfigFromXML = nil;
}
CLDAPPlugIn::~CLDAPPlugIn ( void )
{
if ( pConfigFromXML != nil)
{
delete ( pConfigFromXML );
pConfigFromXML = nil;
gConfigTable = nil;
gConfigTableLen = 0;
pStdAttributeMapTuple = nil;
pStdRecordMapTuple = nil;
}
if ( gContinueTable != nil)
{
delete ( gContinueTable );
gContinueTable = nil;
}
if ( gLDAPOpenMutex != nil )
{
delete(gLDAPOpenMutex);
gLDAPOpenMutex = nil;
}
}
sInt32 CLDAPPlugIn::Validate ( const char *inVersionStr, const uInt32 inSignature )
{
fSignature = inSignature;
return( noErr );
}
sInt32 CLDAPPlugIn::Initialize ( void )
{
int countNodes = 0;
sInt32 siResult = eDSNoErr;
tDataList *pldapName = nil;
sLDAPConfigData *pConfig = nil;
uInt32 iTableIndex = 0;
try
{
if ( pConfigFromXML == nil )
{
pConfigFromXML = new CLDAPConfigs();
if ( pConfigFromXML == nil ) throw( (sInt32)eDSOpenNodeFailed ); }
siResult = pConfigFromXML->Init( gConfigTable, gConfigTableLen, &pStdAttributeMapTuple, &pStdRecordMapTuple );
if ( siResult != eDSNoErr ) throw( siResult );
for (iTableIndex=1; iTableIndex<gConfigTableLen; iTableIndex++)
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( iTableIndex );
if (pConfig != nil)
{
if (pConfig->fServerName != nil)
{
if (pConfig->bUpdated)
{
{
countNodes++;
pConfig->bAvail = true;
pldapName = dsBuildListFromStringsPriv((char *)"LDAPv2", pConfig->fServerName, nil);
if (pldapName != nil)
{
DSRegisterNode( fSignature, pldapName, kDirNodeType );
dsDataListDeallocatePriv( pldapName);
free(pldapName);
pldapName = nil;
}
} } else
{
pldapName = dsBuildListFromStringsPriv((char *)"LDAPv2", pConfig->fServerName, nil);
if (pldapName != nil)
{
DSUnregisterNode( fSignature, pldapName );
dsDataListDeallocatePriv( pldapName);
free(pldapName);
pldapName = nil;
}
pConfigFromXML->CleanLDAPConfigData( pConfig );
delete( pConfig );
pConfig = nil;
gConfigTable->RemoveItem( iTableIndex );
}
} } }
fState = kUnknownState;
fState += kInitalized;
fState += kActive;
WakeUpRequests();
} catch( sInt32 err )
{
siResult = err;
fState = kUnknownState;
fState += kFailedToInit;
}
return( siResult );
}
sInt32 CLDAPPlugIn::SetPluginState ( const uInt32 inState )
{
tDataList *pldapName = nil;
sLDAPConfigData *pConfig = nil;
uInt32 iTableIndex = 0;
if (kActive & inState) {
Initialize();
}
if (kInactive & inState) {
for (iTableIndex=1; iTableIndex<gConfigTableLen; iTableIndex++)
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( iTableIndex );
if (pConfig != nil)
{
if (pConfig->fServerName != nil)
{
{
pldapName = dsBuildListFromStringsPriv((char *)"LDAPv2", pConfig->fServerName, nil);
if (pldapName != nil)
{
DSUnregisterNode( fSignature, pldapName );
dsDataListDeallocatePriv( pldapName);
free(pldapName);
pldapName = nil;
}
}
} } }
if (!(fState & kInactive))
{
fState += kInactive;
}
if (fState & kActive)
{
fState -= kActive;
}
}
return( eDSNoErr );
}
void CLDAPPlugIn::WakeUpRequests ( void )
{
gKickSearchRequests->Signal();
}
void CLDAPPlugIn::WaitForInit ( void )
{
volatile uInt32 uiAttempts = 0;
if (!(fState & kActive))
{
while ( !(fState & kInitalized) &&
!(fState & kFailedToInit) )
{
try
{
if ( uiAttempts++ >= 240 )
{
return;
}
gKickSearchRequests->Wait( (uInt32)(.5 * kMilliSecsPerSec) );
try
{
gKickSearchRequests->Reset();
}
catch( sInt32 err )
{
}
}
catch( sInt32 err1 )
{
}
}
}}
sInt32 CLDAPPlugIn::ProcessRequest ( void *inData )
{
sInt32 siResult = 0;
char *pathStr = nil;
if ( inData == nil )
{
return( ePlugInDataError );
}
if (((sHeader *)inData)->fType == kOpenDirNode)
{
if (((sOpenDirNode *)inData)->fInDirNodeName != nil)
{
pathStr = ::dsGetPathFromListPriv( ((sOpenDirNode *)inData)->fInDirNodeName, "/" );
if (pathStr != nil)
{
if (strncmp(pathStr,"/LDAPv2",7) != 0)
{
free(pathStr);
pathStr = nil;
return(eDSOpenNodeFailed);
}
free(pathStr);
pathStr = nil;
}
}
}
WaitForInit();
if ( (fState & kFailedToInit) )
{
return( ePlugInFailedToInitialize );
}
if ( ((fState & kInactive) || !(fState & kActive))
&& (((sHeader *)inData)->fType != kDoPlugInCustomCall)
&& (((sHeader *)inData)->fType != kOpenDirNode) )
{
return( ePlugInNotActive );
}
if ( ((sHeader *)inData)->fType == kHandleNetworkTransition )
{
siResult = Initialize(); }
else
{
siResult = HandleRequest( inData );
}
return( siResult );
}
sInt32 CLDAPPlugIn::HandleRequest ( void *inData )
{
sInt32 siResult = 0;
sHeader *pMsgHdr = nil;
if ( inData == nil )
{
return( -8088 );
}
pMsgHdr = (sHeader *)inData;
switch ( pMsgHdr->fType )
{
case kOpenDirNode:
siResult = OpenDirNode( (sOpenDirNode *)inData );
break;
case kCloseDirNode:
siResult = CloseDirNode( (sCloseDirNode *)inData );
break;
case kGetDirNodeInfo:
siResult = GetDirNodeInfo( (sGetDirNodeInfo *)inData );
break;
case kGetRecordList:
siResult = GetRecordList( (sGetRecordList *)inData );
break;
case kGetRecordEntry:
siResult = GetRecordEntry( (sGetRecordEntry *)inData );
break;
case kGetAttributeEntry:
siResult = GetAttributeEntry( (sGetAttributeEntry *)inData );
break;
case kGetAttributeValue:
siResult = GetAttributeValue( (sGetAttributeValue *)inData );
break;
case kOpenRecord:
siResult = OpenRecord( (sOpenRecord *)inData );
break;
case kGetRecordReferenceInfo:
siResult = GetRecRefInfo( (sGetRecRefInfo *)inData );
break;
case kGetRecordAttributeInfo:
siResult = GetRecAttribInfo( (sGetRecAttribInfo *)inData );
break;
case kGetRecordAttributeValueByID:
siResult = eNotYetImplemented;
break;
case kGetRecordAttributeValueByIndex:
siResult = GetRecAttrValueByIndex( (sGetRecordAttributeValueByIndex *)inData );
break;
case kFlushRecord:
siResult = eNotYetImplemented;
break;
case kCloseAttributeList:
siResult = CloseAttributeList( (sCloseAttributeList *)inData );
break;
case kCloseAttributeValueList:
siResult = CloseAttributeValueList( (sCloseAttributeValueList *)inData );
break;
case kCloseRecord:
siResult = CloseRecord( (sCloseRecord *)inData );
break;
case kSetRecordName:
siResult = eNotYetImplemented;
break;
case kSetRecordType:
siResult = eNotYetImplemented;
break;
case kDeleteRecord:
siResult = eNotYetImplemented;
break;
case kCreateRecord:
siResult = eNotYetImplemented;
break;
case kCreateRecordAndOpen:
siResult = eNotYetImplemented;
break;
case kAddAttribute:
siResult = eNotYetImplemented;
break;
case kRemoveAttribute:
siResult = eNotYetImplemented;
break;
case kAddAttributeValue:
siResult = eNotYetImplemented;
break;
case kRemoveAttributeValue:
siResult = eNotYetImplemented;
break;
case kSetAttributeValue:
siResult = eNotYetImplemented;
break;
case kDoDirNodeAuth:
siResult = DoAuthentication( (sDoDirNodeAuth *)inData );
break;
case kDoAttributeValueSearch:
case kDoAttributeValueSearchWithData:
siResult = DoAttributeValueSearch( (sDoAttrValueSearchWithData *)inData );
break;
case kDoPlugInCustomCall:
siResult = DoPlugInCustomCall( (sDoPlugInCustomCall *)inData );
break;
default:
siResult = eNotHandledByThisNode;
break;
}
pMsgHdr->fResult = siResult;
return( siResult );
}
sInt32 CLDAPPlugIn::OpenDirNode ( sOpenDirNode *inData )
{
char *ldapName = nil;
char *pathStr = nil;
char *subStr = nil;
int ldapPort = LDAP_PORT;
sLDAPContextData *pContext = nil;
sInt32 siResult = eDSNoErr;
sLDAPConfigData *pConfig = nil;
uInt32 iTableIndex = 0;
tDataListPtr pNodeList = nil;
LDAP *ald = nil;
pNodeList = inData->fInDirNodeName;
PrintNodeName(pNodeList);
try
{
if ( inData != nil )
{
pathStr = dsGetPathFromListPriv( pNodeList, (char *)"/" );
if ( pathStr == nil ) throw( (sInt32)eDSNullNodeName );
if (::strcmp(pathStr,"/LDAPv2") == 0)
{
pContext = MakeContextData();
pContext->fHost = nil;
pContext->fName = new char[1+::strlen("LDAPv2 Configure")];
::strcpy(pContext->fName,"LDAPv2 Configure");
pContext->fConfigTableIndex = 0;
gRefTable->AddItem( inData->fOutNodeRef, pContext );
}
else if ( (strlen(pathStr) > 8) && (::strncmp(pathStr,"/LDAPv2/",8) == 0) )
{
subStr = pathStr + 8;
ldapName = new char[1+strlen(subStr)];
if ( ldapName == nil ) throw( (sInt32)eDSNullNodeName );
::strcpy(ldapName,subStr);
for (iTableIndex=0; iTableIndex<gConfigTableLen; iTableIndex++)
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( iTableIndex );
if (pConfig != nil)
{
if (pConfig->fName != nil)
{
if (::strcmp(pConfig->fServerName,ldapName) == 0)
{
ldapPort = pConfig->fServerPort;
break;
} } } }
gLDAPOpenMutex->Wait();
ald = ldap_open(ldapName, ldapPort);
gLDAPOpenMutex->Signal();
if ( ald != NULL )
{
pContext = MakeContextData();
pContext->fHost = ald;
pContext->fName = new char[1+::strlen(ldapName)];
::strcpy(pContext->fName,ldapName);
pContext->fPort = ldapPort;
pContext->fType = 1;
if (iTableIndex < gConfigTableLen)
{
pContext->fConfigTableIndex = iTableIndex;
}
else {
pContext->fConfigTableIndex = 0;
}
gRefTable->AddItem( inData->fOutNodeRef, pContext );
} else
{
siResult = eDSOpenNodeFailed;
}
if ( ldapName != nil )
{
delete( ldapName );
ldapName = nil;
}
} else
{
siResult = eDSOpenNodeFailed;
}
delete( pathStr );
pathStr = nil;
} } catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPPlugIn::CloseDirNode ( sCloseDirNode *inData )
{
int ldapResult = LDAP_SUCCESS;
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
try
{
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
if ( pContext->fHost != nil )
{
ldapResult = ldap_unbind(pContext->fHost);
if (ldapResult != LDAP_SUCCESS)
{
siResult = eDSNodeNotFound;
}
}
gRefTable->RemoveItem( inData->fInNodeRef );
gContinueTable->RemoveItems( inData->fInNodeRef );
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sLDAPContextData* CLDAPPlugIn::MakeContextData ( void )
{
sLDAPContextData *pOut = nil;
sInt32 siResult = eDSNoErr;
pOut = (sLDAPContextData *) calloc(1, sizeof(sLDAPContextData));
if ( pOut != nil )
{
siResult = CleanContextData(pOut);
}
return( pOut );
}
sInt32 CLDAPPlugIn::CleanContextData ( sLDAPContextData *inContext )
{
sInt32 siResult = eDSNoErr;
if ( inContext == nil )
{
siResult = eDSBadContextData;
}
else
{
inContext->fHost = nil;
if (inContext->fName != nil)
{
delete ( inContext->fName );
}
inContext->fName = nil;
inContext->fPort = 389;
inContext->fConfigTableIndex= 0;
inContext->fType = 0; inContext->msgId = 0;
inContext->authCallActive = false;
if (inContext->authAccountName != nil)
{
delete ( inContext->authAccountName );
}
inContext->authAccountName = nil;
if (inContext->authPassword != nil)
{
delete ( inContext->authPassword );
}
inContext->authPassword = nil;
if (inContext->pResult != nil)
{
ldap_msgfree( inContext->pResult );
inContext->pResult = nil;
}
inContext->fRecNameIndex = 1;
inContext->fRecTypeIndex = 1;
inContext->fAttrIndex = 1;
inContext->offset = 0;
inContext->index = 1;
inContext->attrCnt = 0;
if (inContext->fOpenRecordType != nil)
{
delete ( inContext->fOpenRecordType );
}
inContext->fOpenRecordType = nil;
if (inContext->fOpenRecordName != nil)
{
delete ( inContext->fOpenRecordName );
}
inContext->fOpenRecordName = nil;
}
return( siResult );
}
void CLDAPPlugIn::PrintNodeName ( tDataListPtr inNodeList )
{
char *pPath = nil;
pPath = dsGetPathFromListPriv( inNodeList, (char *)"/" );
if ( pPath != nil )
{
CShared::LogIt( 0x0F, (char *)"CLDAPPlugIn::PrintNodeName" );
CShared::LogIt( 0x0F, pPath );
delete( pPath );
pPath = nil;
}
}
sInt32 CLDAPPlugIn::GetRecordList ( sGetRecordList *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiTotal = 0;
uInt32 uiCount = 0;
char *pRecName = nil;
char *pRecType = nil;
char *pLDAPRecType = nil;
bool bAttribOnly = false;
tDirPatternMatch pattMatch = eDSNoMatch1;
CAttributeList *cpRecNameList = nil;
CAttributeList *cpRecTypeList = nil;
CAttributeList *cpAttrTypeList = nil;
sLDAPContextData *pContext = nil;
CBuff *outBuff = nil;
int numRecTypes = 1;
bool bBuffFull = false;
bool separateRecTypes = false;
uInt32 countDownRecTypes = 0;
try
{
if ( inData == nil ) throw( (sInt32)eMemoryError );
if ( inData->fInDataBuff == nil ) throw( (sInt32)eDSEmptyBuffer );
if (inData->fInDataBuff->fBufferSize == 0) throw( (sInt32)eDSEmptyBuffer );
if ( inData->fInRecNameList == nil ) throw( (sInt32)eDSEmptyRecordNameList );
if ( inData->fInRecTypeList == nil ) throw( (sInt32)eDSEmptyRecordTypeList );
if ( inData->fInAttribTypeList == nil ) throw( (sInt32)eDSEmptyAttributeTypeList );
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
if ( inData->fIOContinueData != nil )
{
if ( inData->fIOContinueData != pContext )
{
throw( (sInt32)eDSInvalidContext );
}
}
else
{
pContext->fRecNameIndex = 1;
pContext->fRecTypeIndex = 1;
pContext->fAttrIndex = 1;
pContext->fTotalRecCount = 0;
pContext->fLimitRecSearch = 0;
if (inData->fOutRecEntryCount >= 0)
{
pContext->fLimitRecSearch = inData->fOutRecEntryCount;
}
}
inData->fIOContinueData = nil;
inData->fOutRecEntryCount = 0;
outBuff = new CBuff();
if ( outBuff == nil ) throw( (sInt32)eMemoryError );
siResult = outBuff->Initialize( inData->fInDataBuff, true );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = outBuff->GetBuffStatus();
if ( siResult != eDSNoErr ) throw( siResult );
siResult = outBuff->SetBuffType( 'StdA' );
if ( siResult != eDSNoErr ) throw( siResult );
cpRecNameList = new CAttributeList( inData->fInRecNameList );
if ( cpRecNameList == nil ) throw( (sInt32)eDSEmptyRecordNameList );
if (cpRecNameList->GetCount() == 0) throw( (sInt32)eDSEmptyRecordNameList );
pattMatch = inData->fInPatternMatch;
cpRecTypeList = new CAttributeList( inData->fInRecTypeList );
if ( cpRecTypeList == nil ) throw( (sInt32)eDSEmptyRecordTypeList );
countDownRecTypes = cpRecTypeList->GetCount() - pContext->fRecTypeIndex + 1;
if (cpRecTypeList->GetCount() == 0) throw( (sInt32)eDSEmptyRecordTypeList );
cpAttrTypeList = new CAttributeList( inData->fInAttribTypeList );
if ( cpAttrTypeList == nil ) throw( (sInt32)eDSEmptyAttributeTypeList );
if (cpAttrTypeList->GetCount() == 0) throw( (sInt32)eDSEmptyAttributeTypeList );
bAttribOnly = inData->fInAttribInfoOnly;
while ((( cpRecTypeList->GetAttribute( pContext->fRecTypeIndex, &pRecType ) == eDSNoErr ) && (!bBuffFull)) && (!separateRecTypes))
{
numRecTypes = 1;
pLDAPRecType = MapRecToLDAPType( pRecType, pContext->fConfigTableIndex, numRecTypes );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while (( pLDAPRecType != nil ) && (!bBuffFull))
{
while (( (cpRecNameList->GetAttribute( pContext->fRecNameIndex, &pRecName ) == eDSNoErr) && ( siResult == eDSNoErr) ) && (!bBuffFull))
{
bBuffFull = false;
if ( ::strcmp( pRecName, kDSRecordsAll ) == 0 )
{
siResult = GetAllRecords( pRecType, pLDAPRecType, cpAttrTypeList, pContext, bAttribOnly, outBuff, uiCount );
}
else
{
siResult = GetTheseRecords( pRecName, pRecType, pLDAPRecType, pattMatch, cpAttrTypeList, pContext, bAttribOnly, outBuff, uiCount );
}
if ( siResult == CBuff::kBuffFull )
{
bBuffFull = true;
inData->fIOContinueData = pContext;
if (uiCount == 0)
{
throw( (sInt32)eDSBufferTooSmall );
}
uiTotal += uiCount;
inData->fOutRecEntryCount = uiTotal;
outBuff->SetLengthToSize();
siResult = eDSNoErr;
}
else if ( siResult == eDSNoErr )
{
uiTotal += uiCount;
pContext->fRecNameIndex++;
}
}
if (pLDAPRecType != nil)
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if (!bBuffFull)
{
numRecTypes++;
pLDAPRecType = MapRecToLDAPType( pRecType, pContext->fConfigTableIndex, numRecTypes );
}
}
if (!bBuffFull)
{
pRecType = nil;
pContext->fRecTypeIndex++;
pContext->fRecNameIndex = 1;
pContext->msgId = 0;
separateRecTypes = true;
inData->fIOContinueData = pContext;
siResult = eDSNoErr;
countDownRecTypes--;
if (countDownRecTypes == 0)
{
inData->fIOContinueData = nil;
}
}
}
if (( siResult == eDSNoErr ) & (!bBuffFull))
{
if ( uiTotal == 0 )
{
outBuff->ClearBuff();
}
else
{
outBuff->SetLengthToSize();
}
inData->fOutRecEntryCount = uiTotal;
}
}
catch( sInt32 err )
{
siResult = err;
}
if (pLDAPRecType != nil)
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if ( cpRecNameList != nil )
{
delete( cpRecNameList );
cpRecNameList = nil;
}
if ( cpRecTypeList != nil )
{
delete( cpRecTypeList );
cpRecTypeList = nil;
}
if ( cpAttrTypeList != nil )
{
delete( cpAttrTypeList );
cpAttrTypeList = nil;
}
if ( outBuff != nil )
{
delete( outBuff );
outBuff = nil;
}
return( siResult );
}
char* CLDAPPlugIn::MapRecToLDAPType ( char *inRecType, uInt32 inConfigTableIndex, int inIndex )
{
char *outResult = nil;
uInt32 uiStrLen = 0;
uInt32 uiNativeLen = ::strlen( kDSNativeRecordTypePrefix );
uInt32 uiStdLen = ::strlen( kDSStdRecordTypePrefix );
sLDAPConfigData *pConfig = nil;
sMapTuple *pMapTuple = nil;
int countNative = 0;
sPtrString *pPtrString = nil;
bool foundMap = false;
if ( ( inRecType != nil ) && (inIndex > 0) )
{
uiStrLen = ::strlen( inRecType );
if ( ::strncmp( inRecType, kDSNativeRecordTypePrefix, uiNativeLen ) == 0 )
{
if ( ( uiStrLen > uiNativeLen ) && (inIndex == 1) )
{
uiStrLen = uiStrLen - uiNativeLen;
outResult = new char[ uiStrLen + 2 ];
::strcpy( outResult, inRecType + uiNativeLen );
}
} else if ( ::strncmp( inRecType, kDSStdRecordTypePrefix, uiStdLen ) == 0 )
{
if (( inConfigTableIndex < gConfigTableLen) && ( inConfigTableIndex >= 0 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inConfigTableIndex );
if (pConfig != nil)
{
pMapTuple = pConfig->pRecordMapTuple;
}
}
if ( pMapTuple == nil )
{
pMapTuple = pStdRecordMapTuple;
}
if ( pMapTuple != nil )
{
while ((pMapTuple != nil) && !(foundMap))
{
if (pMapTuple->fStandard != nil)
{
if (::strcmp( inRecType, pMapTuple->fStandard ) == 0 )
{
pPtrString = pMapTuple->fNative;
countNative = 0;
while ((pPtrString != nil) && !(foundMap))
{
if (pPtrString->fName != nil)
{
countNative++;
if (inIndex == countNative)
{
outResult = new char[1+::strlen( pPtrString->fName )];
::strcpy( outResult, pPtrString->fName );
foundMap = true;
}
}
pPtrString = pPtrString->pNext;
} } } pMapTuple = pMapTuple->pNext;
} } } else
{
if ( inIndex == 1 )
{
outResult = new char[ 1 + ::strlen( inRecType ) ];
::strcpy( outResult, inRecType );
}
}
}
return( outResult );
}
sInt32 CLDAPPlugIn::GetAllRecords ( char *inRecType,
char *inNativeRecType,
CAttributeList *inAttrTypeList,
sLDAPContextData *inContext,
bool inAttrOnly,
CBuff *inBuff,
uInt32 &outRecCount )
{
sInt32 siResult = eDSNoErr;
sInt32 siValCnt = 0;
int ldapReturnCode = 0;
int ldapMsgId = 0;
bool bufferFull = false;
LDAPMessage *result = nil;
char *recName = nil;
sLDAPConfigData *pConfig = nil;
int searchTO = 0;
CDataBuff *aRecData = nil;
CDataBuff *aAttrData = nil;
outRecCount = 0;
try
{
if (inContext == nil ) throw( (sInt32)eDSInvalidContext);
aRecData = new CDataBuff();
if ( aRecData == nil ) throw( (sInt32)eMemoryError );
aAttrData = new CDataBuff();
if ( aAttrData == nil ) throw( (sInt32)eMemoryError );
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
siResult = RebindTryProc(inContext);
if ( siResult != eDSNoErr ) throw( siResult );
if (inContext->msgId == 0)
{
if ( (ldapMsgId = ldap_search( inContext->fHost, inNativeRecType, LDAP_SCOPE_SUBTREE, (char *)"(objectclass=*)", NULL, 0) ) == -1 )
{
throw( (sInt32)eDSNoErr); }
inContext->msgId = ldapMsgId;
} else
{
ldapMsgId = inContext->msgId;
}
if ( (inContext->fTotalRecCount < inContext->fLimitRecSearch) || (inContext->fLimitRecSearch == 0) )
{
if (inContext->pResult != nil)
{
result = inContext->pResult;
ldapReturnCode = LDAP_RES_SEARCH_ENTRY;
}
else
{
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
}
while ( ( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) && !(bufferFull) &&
( (inContext->fTotalRecCount < inContext->fLimitRecSearch) || (inContext->fLimitRecSearch == 0) ) )
{
aAttrData->Clear();
aRecData->Clear();
if ( inRecType != nil )
{
aRecData->AppendShort( ::strlen( inRecType ) );
aRecData->AppendString( inRecType );
} else
{
aRecData->AppendShort( ::strlen( "Record Type Unknown" ) );
aRecData->AppendString( "Record Type Unknown" );
}
recName = GetRecordName( result, inContext, siResult );
if ( siResult != eDSNoErr ) throw( siResult );
if ( recName != nil )
{
aRecData->AppendShort( ::strlen( recName ) );
aRecData->AppendString( recName );
delete ( recName );
recName = nil;
}
else
{
aRecData->AppendShort( ::strlen( "Record Name Unknown" ) );
aRecData->AppendString( "Record Name Unknown" );
}
aAttrData->Clear();
siResult = GetTheseAttributes( inAttrTypeList, result, inAttrOnly, inContext, siValCnt, aAttrData );
if ( siResult != eDSNoErr ) throw( siResult );
if ( siValCnt == 0 )
{
aRecData->AppendShort( 0 );
}
else
{
aRecData->AppendShort( siValCnt );
aRecData->AppendBlock( aAttrData->GetData(), aAttrData->GetLength() );
}
siResult = inBuff->AddData( aRecData->GetData(), aRecData->GetLength() );
if (siResult == CBuff::kBuffFull)
{
bufferFull = true;
inContext->pResult = result;
}
else if ( siResult == eDSNoErr )
{
ldap_msgfree( result );
outRecCount++; inContext->fTotalRecCount++;
inContext->pResult = nil;
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
else
{
inContext->pResult = nil;
throw( (sInt32)eDSInvalidBuffFormat);
}
}
if (ldapReturnCode == LDAP_TIMEOUT)
{
siResult = eDSServerTimeout;
}
if ( (result != inContext->pResult) && (result != nil) )
{
ldap_msgfree( result );
result = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if (aRecData != nil)
{
delete (aRecData);
aRecData = nil;
}
if (aAttrData != nil)
{
delete (aAttrData);
aAttrData = nil;
}
return( siResult );
}
sInt32 CLDAPPlugIn::GetRecordEntry ( sGetRecordEntry *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiIndex = 0;
uInt32 uiCount = 0;
uInt32 uiOffset = 0;
uInt32 uberOffset = 0;
char *pData = nil;
tRecordEntryPtr pRecEntry = nil;
sLDAPContextData *pContext = nil;
CBuff inBuff;
uInt32 offset = 0;
uInt16 usTypeLen = 0;
char *pRecType = nil;
uInt16 usNameLen = 0;
char *pRecName = nil;
uInt16 usAttrCnt = 0;
uInt32 buffLen = 0;
try
{
if ( inData == nil ) throw( (sInt32)eMemoryError );
if ( inData->fInOutDataBuff == nil ) throw( (sInt32)eDSEmptyBuffer );
if (inData->fInOutDataBuff->fBufferSize == 0) throw( (sInt32)eDSEmptyBuffer );
siResult = inBuff.Initialize( inData->fInOutDataBuff );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = inBuff.GetDataBlockCount( &uiCount );
if ( siResult != eDSNoErr ) throw( siResult );
uiIndex = inData->fInRecEntryIndex;
if ((uiIndex > uiCount) || (uiIndex == 0)) throw( (sInt32)eDSInvalidIndex );
pData = inBuff.GetDataBlock( uiIndex, &uberOffset );
if ( pData == nil ) throw( (sInt32)eDSCorruptBuffer );
buffLen = inBuff.GetDataBlockLength( uiIndex );
pData += 4;
offset = 0;
if (2 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usTypeLen, pData, 2 );
pData += 2;
offset += 2;
pRecType = pData;
pData += usTypeLen;
offset += usTypeLen;
if (2 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usNameLen, pData, 2 );
pData += 2;
offset += 2;
pRecName = pData;
pData += usNameLen;
offset += usNameLen;
if (2 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrCnt, pData, 2 );
pRecEntry = (tRecordEntry *)::calloc( 1, sizeof( tRecordEntry ) + usNameLen + usTypeLen + 4 + kBuffPad );
pRecEntry->fRecordNameAndType.fBufferSize = usNameLen + usTypeLen + 4 + kBuffPad;
pRecEntry->fRecordNameAndType.fBufferLength = usNameLen + usTypeLen + 4;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData, &usNameLen, 2 );
uiOffset += 2;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, pRecName, usNameLen );
uiOffset += usNameLen;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, &usTypeLen, 2 );
uiOffset += 2;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, pRecType, usTypeLen );
pRecEntry->fRecordAttributeCount = usAttrCnt;
pContext = MakeContextData();
if ( pContext == nil ) throw( (sInt32)eMemoryAllocError );
pContext->offset = uberOffset + offset + 4;
gRefTable->AddItem( inData->fOutAttrListRef, pContext );
inData->fOutRecEntryPtr = pRecEntry;
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPPlugIn::GetRecInfo ( char *inData, tRecordEntryPtr *outRecInfo )
{
uInt32 siResult = eDSNoErr;
uInt32 uiOffset = 0;
char *p = inData;
uInt16 usTypeLen = 0;
char *pRecType = nil;
uInt16 usNameLen = 0;
char *pRecName = nil;
uInt16 usAttrCnt = 0;
tRecordEntry *pTmpRecInfo = nil;
if ( siResult == eDSNoErr )
{
p += 4;
::memcpy( &usTypeLen, p, 2 );
p += 2;
pRecType = p;
p += usTypeLen;
::memcpy( &usNameLen, p, 2 );
p += 2;
pRecName = p + uiOffset;
p += usNameLen;
::memcpy( &usAttrCnt, p, 2 );
pTmpRecInfo = (tRecordEntry *)::calloc( 1, sizeof( tRecordEntry ) + usNameLen + usTypeLen + kBuffPad );
pTmpRecInfo->fRecordNameAndType.fBufferSize = usNameLen + usTypeLen + 4;
pTmpRecInfo->fRecordNameAndType.fBufferLength = usNameLen + usTypeLen + 4;
::memcpy( pTmpRecInfo->fRecordNameAndType.fBufferData, &usNameLen, 2 );
uiOffset += 2;
::memcpy( pTmpRecInfo->fRecordNameAndType.fBufferData + uiOffset, pRecName, usNameLen );
uiOffset += usNameLen;
::memcpy( pTmpRecInfo->fRecordNameAndType.fBufferData + uiOffset, &usTypeLen, 2 );
uiOffset += 2;
::memcpy( pTmpRecInfo->fRecordNameAndType.fBufferData + uiOffset, pRecType, usTypeLen );
pTmpRecInfo->fRecordAttributeCount = usAttrCnt;
*outRecInfo = pTmpRecInfo;
}
return( siResult );
}
sInt32 CLDAPPlugIn::GetTheseAttributes (CAttributeList *inAttrTypeList,
LDAPMessage *inResult,
bool inAttrOnly,
sLDAPContextData *inContext,
sInt32 &outCount,
CDataBuff *inDataBuff )
{
sInt32 siResult = eDSNoErr;
sInt32 attrTypeIndex = 1;
char *pLDAPAttrType = nil;
char *pAttrType = nil;
char *pAttr = nil;
BerElement *ber;
struct berval **bValues;
int numAttributes = 1;
int numStdAttributes = 1;
bool bTypeFound = false;
int valCount = 0;
char *pStdAttrType = nil;
bool bAtLeastOneTypeValid = false;
CDataBuff *aTmpData = nil;
CDataBuff *aTmp2Data = nil;
bool bStripCryptPrefix = false;
bool bUsePlus = true;
char *pLDAPPasswdAttrType = nil;
try
{
if ( inContext == nil ) throw( (sInt32)eDSBadContextData );
outCount = 0;
aTmpData = new CDataBuff();
if ( aTmpData == nil ) throw( (sInt32)eMemoryError );
aTmp2Data = new CDataBuff();
if ( aTmp2Data == nil ) throw( (sInt32)eMemoryError );
inDataBuff->Clear();
while ( inAttrTypeList->GetAttribute( attrTypeIndex++, &pAttrType ) == eDSNoErr )
{
siResult = eDSNoErr;
if ( ::strcmp( kDSNAttrMetaNodeLocation, pAttrType ) == 0 )
{
aTmpData->Clear();
outCount++;
aTmpData->AppendShort( ::strlen( pAttrType ) );
aTmpData->AppendString( pAttrType );
if ( inAttrOnly == false )
{
aTmpData->AppendShort( 1 );
char *tmpStr = nil;
if ( inContext->fName != nil )
{
tmpStr = new char[1+8+::strlen(inContext->fName)];
::strcpy( tmpStr, "/LDAPv2/" );
::strcat( tmpStr, inContext->fName );
}
else
{
tmpStr = new char[1+::strlen("Unknown Node Location")];
::strcpy( tmpStr, "Unknown Node Location" );
}
aTmpData->AppendLong( ::strlen( tmpStr ) );
aTmpData->AppendString( tmpStr );
delete( tmpStr );
inDataBuff->AppendLong( aTmpData->GetLength() );
inDataBuff->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
} } else if ((::strcmp(pAttrType,kDSAttributesAll) == 0) || (::strcmp(pAttrType,kDSAttributesStandardAll) == 0) || (::strcmp(pAttrType,kDSAttributesNativeAll) == 0))
{
if ((::strcmp(pAttrType,kDSAttributesAll) == 0) || (::strcmp(pAttrType,kDSAttributesStandardAll) == 0))
{
aTmpData->Clear();
outCount++;
aTmpData->AppendShort( ::strlen( kDSNAttrMetaNodeLocation ) );
aTmpData->AppendString( kDSNAttrMetaNodeLocation );
if ( inAttrOnly == false )
{
aTmpData->AppendShort( 1 );
char *tmpStr = nil;
if ( inContext->fName != nil )
{
tmpStr = new char[1+8+::strlen(inContext->fName)];
::strcpy( tmpStr, "/LDAPv2/" );
::strcat( tmpStr, inContext->fName );
}
else
{
tmpStr = new char[1+::strlen("Unknown Node Location")];
::strcpy( tmpStr, "Unknown Node Location" );
}
aTmpData->AppendLong( ::strlen( tmpStr ) );
aTmpData->AppendString( tmpStr );
delete( tmpStr );
inDataBuff->AppendLong( aTmpData->GetLength() );
inDataBuff->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
pLDAPPasswdAttrType = MapAttrToLDAPType( kDS1AttrPassword, inContext->fConfigTableIndex, 1 );
numStdAttributes = 1;
pStdAttrType = GetNextStdAttrType( inContext->fConfigTableIndex, numStdAttributes );
while ( pStdAttrType != nil )
{
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pStdAttrType, inContext->fConfigTableIndex, numAttributes );
bAtLeastOneTypeValid = false;
bTypeFound = false;
while ( pLDAPAttrType != nil )
{
for ( pAttr = ldap_first_attribute (inContext->fHost, inResult, &ber );
pAttr != NULL; pAttr = ldap_next_attribute(inContext->fHost, inResult, ber ) )
{
bStripCryptPrefix = false;
if (::strcmp( pAttr, pLDAPAttrType ) == 0)
{
if (pLDAPPasswdAttrType != nil )
{
if ( ( ::strcmp( pAttr, pLDAPPasswdAttrType ) == 0 ) &&
( ::strcmp( pStdAttrType, kDS1AttrPassword ) == 0 ) )
{
bStripCryptPrefix = true;
bUsePlus = false;
delete (pLDAPPasswdAttrType);
pLDAPPasswdAttrType = nil;
}
}
bAtLeastOneTypeValid = true;
if (!bTypeFound)
{
aTmp2Data->Clear();
outCount++;
aTmp2Data->AppendShort( ::strlen( pStdAttrType ) );
aTmp2Data->AppendString( pStdAttrType );
bTypeFound = true;
valCount = 0;
aTmpData->Clear();
}
if (( inAttrOnly == false ) &&
(( bValues = ldap_get_values_len (inContext->fHost, inResult, pAttr )) != NULL) )
{
if (bStripCryptPrefix)
{
bStripCryptPrefix = false; for (int ii = 0; bValues[ii] != NULL; ii++ )
valCount++;
for (int i = 0; bValues[i] != NULL; i++ )
{
if ( ( bValues[i]->bv_len > 7) &&
(strncasecmp(bValues[i]->bv_val,"{crypt}",7) == 0) )
{
aTmpData->AppendLong( bValues[i]->bv_len - 7 );
aTmpData->AppendBlock( (bValues[i]->bv_val) + 7, bValues[i]->bv_len - 7 );
}
else
{
aTmpData->AppendLong( bValues[i]->bv_len );
aTmpData->AppendBlock( bValues[i]->bv_val, bValues[i]->bv_len );
}
} ldap_value_free_len(bValues);
}
else
{
for (int ii = 0; bValues[ii] != NULL; ii++ )
valCount++;
for (int i = 0; bValues[i] != NULL; i++ )
{
aTmpData->AppendLong( bValues[i]->bv_len );
aTmpData->AppendBlock( bValues[i]->bv_val, bValues[i]->bv_len );
} ldap_value_free_len(bValues);
}
}
} if (pAttr != nil)
{
ldap_memfree( pAttr );
}
}
if (ber != nil)
{
ber_free( ber, 0 );
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pStdAttrType, inContext->fConfigTableIndex, numAttributes );
}
if (bAtLeastOneTypeValid)
{
aTmp2Data->AppendShort( valCount );
if (valCount != 0)
{
aTmp2Data->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
valCount = 0;
}
inDataBuff->AppendLong( aTmp2Data->GetLength() );
inDataBuff->AppendBlock( aTmp2Data->GetData(), aTmp2Data->GetLength() );
}
if (pStdAttrType != nil)
{
delete (pStdAttrType);
pStdAttrType = nil;
}
numStdAttributes++;
pStdAttrType = GetNextStdAttrType( inContext->fConfigTableIndex, numStdAttributes );
}
if (bUsePlus)
{
aTmpData->Clear();
outCount++;
aTmpData->AppendShort( ::strlen( kDS1AttrPasswordPlus ) );
aTmpData->AppendString( kDS1AttrPasswordPlus );
if ( inAttrOnly == false )
{
aTmpData->AppendShort( 1 );
aTmpData->AppendLong( 8 );
aTmpData->AppendString( "********" );
inDataBuff->AppendLong( aTmpData->GetLength() );
inDataBuff->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
} }
} if ((::strcmp(pAttrType,kDSAttributesAll) == 0) || (::strcmp(pAttrType,kDSAttributesNativeAll) == 0))
{
for ( pAttr = ldap_first_attribute (inContext->fHost, inResult, &ber );
pAttr != NULL; pAttr = ldap_next_attribute(inContext->fHost, inResult, ber ) )
{
aTmpData->Clear();
outCount++;
if ( pAttr != nil )
{
aTmpData->AppendShort( ::strlen( pAttr ) + ::strlen( kDSNativeAttrTypePrefix ) );
aTmpData->AppendString( (char *)kDSNativeAttrTypePrefix );
aTmpData->AppendString( pAttr );
}
if (( inAttrOnly == false ) &&
(( bValues = ldap_get_values_len (inContext->fHost, inResult, pAttr )) != NULL) )
{
valCount = 0;
for (int ii = 0; bValues[ii] != NULL; ii++ )
valCount++;
aTmpData->AppendShort( valCount );
for (int i = 0; bValues[i] != NULL; i++ )
{
aTmpData->AppendLong( bValues[i]->bv_len );
aTmpData->AppendBlock( bValues[i]->bv_val, bValues[i]->bv_len );
} ldap_value_free_len(bValues);
}
inDataBuff->AppendLong( aTmpData->GetLength() );
inDataBuff->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
}
if (ber != nil)
{
ber_free( ber, 0 );
}
} }
else {
bStripCryptPrefix = false;
numAttributes = 1;
if (::strcmp( kDS1AttrPasswordPlus, pAttrType ) == 0)
{
bStripCryptPrefix = true;
pLDAPAttrType = MapAttrToLDAPType( kDS1AttrPassword, inContext->fConfigTableIndex, numAttributes );
bAtLeastOneTypeValid = false;
bTypeFound = false;
if (pLDAPAttrType == nil)
{
bAtLeastOneTypeValid = true;
aTmp2Data->Clear();
outCount++;
aTmp2Data->AppendShort( ::strlen( pAttrType ) );
aTmp2Data->AppendString( pAttrType );
bTypeFound = true;
valCount = 1;
aTmpData->Clear();
aTmpData->AppendLong( 8 );
aTmpData->AppendString( "********" );
}
}
else
{
pLDAPAttrType = MapAttrToLDAPType( pAttrType, inContext->fConfigTableIndex, numAttributes );
bAtLeastOneTypeValid = false;
bTypeFound = false;
}
while ( pLDAPAttrType != nil )
{
for ( pAttr = ldap_first_attribute (inContext->fHost, inResult, &ber );
pAttr != NULL; pAttr = ldap_next_attribute(inContext->fHost, inResult, ber ) )
{
if (::strcmp( pAttr, pLDAPAttrType ) == 0)
{
bAtLeastOneTypeValid = true;
if (!bTypeFound)
{
aTmp2Data->Clear();
outCount++;
aTmp2Data->AppendShort( ::strlen( pAttrType ) );
aTmp2Data->AppendString( pAttrType );
bTypeFound = true;
valCount = 0;
aTmpData->Clear();
}
if (( inAttrOnly == false ) &&
(( bValues = ldap_get_values_len (inContext->fHost, inResult, pAttr )) != NULL) )
{
if (bStripCryptPrefix)
{
for (int ii = 0; bValues[ii] != NULL; ii++ )
valCount++;
for (int i = 0; bValues[i] != NULL; i++ )
{
if ( ( bValues[i]->bv_len > 7) &&
(strncasecmp(bValues[i]->bv_val,"{crypt}",7) == 0) )
{
aTmpData->AppendLong( bValues[i]->bv_len - 7 );
aTmpData->AppendBlock( (bValues[i]->bv_val) + 7, bValues[i]->bv_len - 7 );
}
else
{
aTmpData->AppendLong( bValues[i]->bv_len );
aTmpData->AppendBlock( bValues[i]->bv_val, bValues[i]->bv_len );
}
} ldap_value_free_len(bValues);
}
else
{
for (int ii = 0; bValues[ii] != NULL; ii++ )
valCount++;
for (int i = 0; bValues[i] != NULL; i++ )
{
aTmpData->AppendLong( bValues[i]->bv_len );
aTmpData->AppendBlock( bValues[i]->bv_val, bValues[i]->bv_len );
} ldap_value_free_len(bValues);
}
}
}
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
}
if (ber != nil)
{
ber_free( ber, 0 );
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pAttrType, inContext->fConfigTableIndex, numAttributes );
}
if (bAtLeastOneTypeValid)
{
aTmp2Data->AppendShort( valCount );
if (valCount != 0)
{
aTmp2Data->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
valCount = 0;
}
inDataBuff->AppendLong( aTmp2Data->GetLength() );
inDataBuff->AppendBlock( aTmp2Data->GetData(), aTmp2Data->GetLength() );
}
}
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( aTmpData != nil )
{
delete( aTmpData );
aTmpData = nil;
}
if ( aTmp2Data != nil )
{
delete( aTmp2Data );
aTmp2Data = nil;
}
return( siResult );
}
char *CLDAPPlugIn::GetRecordName ( LDAPMessage *inResult,
sLDAPContextData *inContext,
sInt32 &errResult )
{
char *recName = nil;
char *pLDAPAttrType = nil;
char *pAttr = nil;
BerElement *ber;
struct berval **bValues;
int numAttributes = 1;
bool bTypeFound = false;
try
{
if ( inContext == nil ) throw( (sInt32)eDSBadContextData );
errResult = eDSNoErr;
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( kDSNAttrRecordName, inContext->fConfigTableIndex, numAttributes );
if (pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttrListRef);
bTypeFound = false;
while ( ( pLDAPAttrType != nil ) && (!bTypeFound) )
{
for ( pAttr = ldap_first_attribute (inContext->fHost, inResult, &ber );
pAttr != NULL; pAttr = ldap_next_attribute(inContext->fHost, inResult, ber ) )
{
if (::strcmp( pAttr, pLDAPAttrType ) == 0)
{
if ( ( bValues = ldap_get_values_len (inContext->fHost, inResult, pAttr )) != NULL )
{
recName = new char[1 + bValues[0]->bv_len];
::strcpy( recName, bValues[0]->bv_val );
bTypeFound = true;
ldap_value_free_len(bValues);
}
}
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
}
if (ber != nil)
{
ber_free( ber, 0 );
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( kDSNAttrRecordName, inContext->fConfigTableIndex, numAttributes );
} if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
}
catch( sInt32 err )
{
errResult = err;
}
return( recName );
}
char* CLDAPPlugIn::MapAttrToLDAPType ( char *inAttrType, uInt32 inConfigTableIndex, int inIndex )
{
char *outResult = nil;
uInt32 uiStrLen = 0;
uInt32 uiNativeLen = ::strlen( kDSNativeAttrTypePrefix );
uInt32 uiStdLen = ::strlen( kDSStdAttrTypePrefix );
sLDAPConfigData *pConfig = nil;
sMapTuple *pMapTuple = nil;
int countNative = 0;
sPtrString *pPtrString = nil;
bool foundMap = false;
if (( inAttrType != nil ) && (inIndex > 0))
{
uiStrLen = ::strlen( inAttrType );
if ( ::strncmp( inAttrType, kDSNativeAttrTypePrefix, uiNativeLen ) == 0 )
{
if (( uiStrLen > uiNativeLen ) && (inIndex == 1))
{
uiStrLen = uiStrLen - uiNativeLen;
outResult = new char[ uiStrLen + 1 ];
::strcpy( outResult, inAttrType + uiNativeLen );
}
} else if ( ::strncmp( inAttrType, kDSStdAttrTypePrefix, uiStdLen ) == 0 )
{
if (( inConfigTableIndex < gConfigTableLen) && ( inConfigTableIndex >= 0 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inConfigTableIndex );
if (pConfig != nil)
{
pMapTuple = pConfig->pAttributeMapTuple;
}
}
if ( pMapTuple == nil )
{
pMapTuple = pStdAttributeMapTuple;
}
if ( pMapTuple != nil )
{
while ((pMapTuple != nil) && !(foundMap))
{
if (pMapTuple->fStandard != nil)
{
if (::strcmp( inAttrType, pMapTuple->fStandard ) == 0 )
{
pPtrString = pMapTuple->fNative;
countNative = 0;
while ((pPtrString != nil) && !(foundMap))
{
if (pPtrString->fName != nil)
{
countNative++;
if (inIndex == countNative)
{
outResult = new char[1+::strlen( pPtrString->fName )];
::strcpy( outResult, pPtrString->fName );
foundMap = true;
}
}
pPtrString = pPtrString->pNext;
} } } pMapTuple = pMapTuple->pNext;
} } } else
{
if ( inIndex == 1 )
{
outResult = new char[ 1 + ::strlen( inAttrType ) ];
::strcpy( outResult, inAttrType );
}
} }
return( outResult );
}
char** CLDAPPlugIn::MapAttrToLDAPTypeArray ( char *inAttrType, uInt32 inConfigTableIndex )
{
char **outResult = nil;
uInt32 uiStrLen = 0;
uInt32 uiNativeLen = ::strlen( kDSNativeAttrTypePrefix );
uInt32 uiStdLen = ::strlen( kDSStdAttrTypePrefix );
sLDAPConfigData *pConfig = nil;
sMapTuple *pMapTuple = nil;
int countNative = 0;
sPtrString *pPtrString = nil;
bool foundMap = false;
if ( inAttrType != nil )
{
uiStrLen = ::strlen( inAttrType );
if ( ::strncmp( inAttrType, kDSNativeAttrTypePrefix, uiNativeLen ) == 0 )
{
if ( uiStrLen > uiNativeLen )
{
uiStrLen = uiStrLen - uiNativeLen;
outResult = (char **)::calloc( 2, sizeof( char * ) );
*outResult = new char[ uiStrLen + 1 ];
::strcpy( *outResult, inAttrType + uiNativeLen );
}
} else if ( ::strncmp( inAttrType, kDSStdAttrTypePrefix, uiStdLen ) == 0 )
{
if (( inConfigTableIndex < gConfigTableLen) && ( inConfigTableIndex >= 0 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inConfigTableIndex );
if (pConfig != nil)
{
pMapTuple = pConfig->pAttributeMapTuple;
}
}
if ( pMapTuple == nil )
{
pMapTuple = pStdAttributeMapTuple;
}
if ( pMapTuple != nil )
{
while ((pMapTuple != nil) && !(foundMap))
{
if (pMapTuple->fStandard != nil)
{
if (::strcmp( inAttrType, pMapTuple->fStandard ) == 0 )
{
foundMap = true;
pPtrString = pMapTuple->fNative;
countNative = 0;
while (pPtrString != nil)
{
if (pPtrString->fName != nil)
{
countNative++;
}
pPtrString = pPtrString->pNext;
} outResult = (char **)::calloc( countNative + 1, sizeof(char *) );
pPtrString = pMapTuple->fNative;
countNative = 0;
while (pPtrString != nil)
{
if (pPtrString->fName != nil)
{
outResult[countNative] = new char[1+::strlen( pPtrString->fName )];
::strcpy( outResult[countNative], pPtrString->fName );
countNative++;
}
pPtrString = pPtrString->pNext;
} } } pMapTuple = pMapTuple->pNext;
} } } else
{
outResult = (char **)::calloc( 2, sizeof(char *) );
*outResult = new char[ 1 + ::strlen( inAttrType ) ];
::strcpy( *outResult, inAttrType );
} }
return( outResult );
}
sInt32 CLDAPPlugIn::GetAttributeEntry ( sGetAttributeEntry *inData )
{
sInt32 siResult = eDSNoErr;
uInt16 usAttrTypeLen = 0;
uInt16 usAttrCnt = 0;
uInt32 usAttrLen = 0;
uInt16 usValueCnt = 0;
uInt32 usValueLen = 0;
uInt32 i = 0;
uInt32 uiIndex = 0;
uInt32 uiAttrEntrySize = 0;
uInt32 uiOffset = 0;
uInt32 uiTotalValueSize = 0;
uInt32 offset = 4;
uInt32 buffSize = 0;
uInt32 buffLen = 0;
char *p = nil;
char *pAttrType = nil;
tDataBufferPtr pDataBuff = nil;
tAttributeEntryPtr pAttribInfo = nil;
sLDAPContextData *pAttrContext = nil;
sLDAPContextData *pValueContext = nil;
try
{
if ( inData == nil ) throw( (sInt32)eMemoryError );
pAttrContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInAttrListRef );
if ( pAttrContext == nil ) throw( (sInt32)eDSBadContextData );
uiIndex = inData->fInAttrInfoIndex;
if (uiIndex == 0) throw( (sInt32)eDSInvalidIndex );
pDataBuff = inData->fInOutDataBuff;
if ( pDataBuff == nil ) throw( (sInt32)eDSNullDataBuff );
buffSize = pDataBuff->fBufferSize;
p = pDataBuff->fBufferData + pAttrContext->offset;
offset = pAttrContext->offset;
if (2 > (sInt32)(buffSize - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrCnt, p, 2 );
if (uiIndex > usAttrCnt) throw( (sInt32)eDSInvalidIndex );
p += 2;
offset += 2;
for ( i = 1; i < uiIndex; i++ )
{
if (4 > (sInt32)(buffSize - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen, p, 4 );
p += 4 + usAttrLen;
offset += 4 + usAttrLen;
}
uiOffset = offset;
if (4 > (sInt32)(buffSize - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen, p, 4 );
p += 4;
offset += 4;
buffLen = offset + usAttrLen;
if (2 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrTypeLen, p, 2 );
pAttrType = p + 2;
p += 2 + usAttrTypeLen;
offset += 2 + usAttrTypeLen;
if (2 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueCnt, p, 2 );
p += 2;
offset += 2;
for ( i = 0; i < usValueCnt; i++ )
{
if (4 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 4 );
p += 4 + usValueLen;
offset += 4 + usValueLen;
uiTotalValueSize += usValueLen;
}
uiAttrEntrySize = sizeof( tAttributeEntry ) + usAttrTypeLen + kBuffPad;
pAttribInfo = (tAttributeEntry *)::calloc( 1, uiAttrEntrySize );
pAttribInfo->fAttributeValueCount = usValueCnt;
pAttribInfo->fAttributeDataSize = uiTotalValueSize;
pAttribInfo->fAttributeValueMaxSize = 512; pAttribInfo->fAttributeSignature.fBufferSize = usAttrTypeLen + kBuffPad;
pAttribInfo->fAttributeSignature.fBufferLength = usAttrTypeLen;
::memcpy( pAttribInfo->fAttributeSignature.fBufferData, pAttrType, usAttrTypeLen );
pValueContext = MakeContextData();
if ( pValueContext == nil ) throw( (sInt32)eMemoryAllocError );
pValueContext->offset = uiOffset;
gRefTable->AddItem( inData->fOutAttrValueListRef, pValueContext );
inData->fOutAttrInfoPtr = pAttribInfo;
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPPlugIn::GetAttributeValue ( sGetAttributeValue *inData )
{
sInt32 siResult = eDSNoErr;
uInt16 usValueCnt = 0;
uInt32 usValueLen = 0;
uInt16 usAttrNameLen = 0;
uInt32 i = 0;
uInt32 uiIndex = 0;
uInt32 offset = 0;
char *p = nil;
tDataBuffer *pDataBuff = nil;
tAttributeValueEntry *pAttrValue = nil;
sLDAPContextData *pValueContext = nil;
uInt32 buffSize = 0;
uInt32 buffLen = 0;
uInt32 attrLen = 0;
try
{
pValueContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInAttrValueListRef );
if ( pValueContext == nil ) throw( (sInt32)eDSBadContextData );
uiIndex = inData->fInAttrValueIndex;
if (uiIndex == 0) throw( (sInt32)eDSInvalidIndex );
pDataBuff = inData->fInOutDataBuff;
if ( pDataBuff == nil ) throw( (sInt32)eDSNullDataBuff );
buffSize = pDataBuff->fBufferSize;
p = pDataBuff->fBufferData + pValueContext->offset;
offset = pValueContext->offset;
if (4 > (sInt32)(buffSize - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &attrLen, p, 4 );
buffLen = attrLen + pValueContext->offset + 4;
if (buffLen > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
p += 4;
offset += 4;
if (2 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrNameLen, p, 2 );
p += 2 + usAttrNameLen;
offset += 2 + usAttrNameLen;
if (2 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueCnt, p, 2 );
p += 2;
offset += 2;
if (uiIndex > usValueCnt) throw( (sInt32)eDSInvalidIndex );
for ( i = 1; i < uiIndex; i++ )
{
if (4 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 4 );
p += 4 + usValueLen;
offset += 4 + usValueLen;
}
if (4 > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 4 );
p += 4;
offset += 4;
pAttrValue = (tAttributeValueEntry *)::calloc( 1, sizeof( tAttributeValueEntry ) + usValueLen + kBuffPad );
pAttrValue->fAttributeValueData.fBufferSize = usValueLen + kBuffPad;
pAttrValue->fAttributeValueData.fBufferLength = usValueLen;
if ( (sInt32)usValueLen > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( pAttrValue->fAttributeValueData.fBufferData, p, usValueLen );
pAttrValue->fAttributeValueID = CalcCRC( pAttrValue->fAttributeValueData.fBufferData );
inData->fOutAttrValue = pAttrValue;
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
uInt32 CLDAPPlugIn::CalcCRC ( char *inStr )
{
char *p = inStr;
sInt32 siI = 0;
sInt32 siStrLen = 0;
uInt32 uiCRC = 0xFFFFFFFF;
CRCCalc aCRCCalc;
if ( inStr != nil )
{
siStrLen = ::strlen( inStr );
for ( siI = 0; siI < siStrLen; ++siI )
{
uiCRC = aCRCCalc.UPDC32( *p, uiCRC );
p++;
}
}
return( uiCRC );
}
sInt32 CLDAPPlugIn::GetTheseRecords ( char *inConstRecName,
char *inConstRecType,
char *inNativeRecType,
tDirPatternMatch patternMatch,
CAttributeList *inAttrTypeList,
sLDAPContextData *inContext,
bool inAttrOnly,
CBuff *inBuff,
uInt32 &outRecCount )
{
sInt32 siResult = eDSNoErr;
sInt32 siValCnt = 0;
int ldapReturnCode = 0;
int ldapMsgId = 0;
bool bufferFull = false;
LDAPMessage *result = nil;
char *recName = nil;
char *queryFilter = nil;
sLDAPConfigData *pConfig = nil;
int searchTO = 0;
CDataBuff *aAttrData = nil;
CDataBuff *aRecData = nil;
queryFilter = BuildLDAPQueryFilter((char *)kDSNAttrRecordName, inConstRecName, patternMatch, inContext->fConfigTableIndex, false);
outRecCount = 0;
try
{
if (inContext == nil ) throw( (sInt32)eDSInvalidContext);
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
aAttrData = new CDataBuff();
if ( aAttrData == nil ) throw( (sInt32)eMemoryError );
aRecData = new CDataBuff();
if ( aRecData == nil ) throw( (sInt32)eMemoryError );
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
siResult = RebindTryProc(inContext);
if ( siResult != eDSNoErr ) throw( siResult );
if ( inContext->msgId == 0 )
{
if ( (ldapMsgId = ldap_search( inContext->fHost, inNativeRecType, LDAP_SCOPE_SUBTREE, queryFilter, NULL, 0) ) == -1 )
{
throw( (sInt32)eDSNoErr); }
inContext->msgId = ldapMsgId;
} else
{
ldapMsgId = inContext->msgId;
}
if ( (inContext->fTotalRecCount < inContext->fLimitRecSearch) || (inContext->fLimitRecSearch == 0) )
{
if (inContext->pResult != nil)
{
result = inContext->pResult;
ldapReturnCode = LDAP_RES_SEARCH_ENTRY;
}
else
{
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
}
while ( ( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) && !(bufferFull) &&
( (inContext->fTotalRecCount < inContext->fLimitRecSearch) || (inContext->fLimitRecSearch == 0) ) )
{
aRecData->Clear();
if ( inConstRecType != nil )
{
aRecData->AppendShort( ::strlen( inConstRecType ) );
aRecData->AppendString( inConstRecType );
}
else
{
aRecData->AppendShort( ::strlen( "Record Type Unknown" ) );
aRecData->AppendString( "Record Type Unknown" );
}
recName = GetRecordName( result, inContext, siResult );
if ( siResult != eDSNoErr ) throw( siResult );
if ( recName != nil )
{
aRecData->AppendShort( ::strlen( recName ) );
aRecData->AppendString( recName );
delete ( recName );
recName = nil;
}
else
{
aRecData->AppendShort( ::strlen( "Record Name Unknown" ) );
aRecData->AppendString( "Record Name Unknown" );
}
aAttrData->Clear();
siResult = GetTheseAttributes( inAttrTypeList, result, inAttrOnly, inContext, siValCnt, aAttrData );
if ( siResult != eDSNoErr ) throw( siResult );
if ( siValCnt == 0 )
{
aRecData->AppendShort( 0 );
}
else
{
aRecData->AppendShort( siValCnt );
aRecData->AppendBlock( aAttrData->GetData(), aAttrData->GetLength() );
}
siResult = inBuff->AddData( aRecData->GetData(), aRecData->GetLength() );
if (siResult == CBuff::kBuffFull)
{
bufferFull = true;
inContext->msgId = ldapMsgId;
inContext->pResult = result;
}
else if ( siResult == eDSNoErr )
{
ldap_msgfree( result );
result = nil;
inContext->msgId = 0;
outRecCount++; inContext->fTotalRecCount++;
inContext->pResult = nil;
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
else
{
inContext->msgId = 0;
inContext->pResult = nil;
throw( (sInt32)eDSInvalidBuffFormat);
}
}
if (ldapReturnCode == LDAP_TIMEOUT)
{
siResult = eDSServerTimeout;
}
if ( (result != inContext->pResult) && (result != nil) )
{
ldap_msgfree( result );
result = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
if (aAttrData != nil)
{
delete (aAttrData);
aAttrData = nil;
}
if (aRecData != nil)
{
delete (aRecData);
aRecData = nil;
}
return( siResult );
}
char *CLDAPPlugIn::BuildLDAPQueryFilter ( char *inConstAttrType,
char *inConstAttrName,
tDirPatternMatch patternMatch,
int inConfigTableIndex,
bool useWellKnownRecType )
{
char *queryFilter = nil;
unsigned long matchType = eDSExact;
char *nativeRecType = nil;
uInt32 recTypeLen = 0;
uInt32 recNameLen = 0;
int numAttributes = 1;
CFMutableStringRef cfStringRef = nil;
char *escapedName = nil;
uInt32 escapedIndex = 0;
uInt32 originalIndex = 0;
bool bOnceThru = false;
uInt32 offset = 3;
uInt32 callocLength = 0;
if (inConstAttrName != nil)
{
recNameLen = strlen(inConstAttrName);
escapedName = (char *)::calloc(1, 2 * recNameLen + 1);
while (originalIndex < recNameLen)
{
switch (inConstAttrName[originalIndex])
{
case '*':
case '(':
case ')':
escapedName[escapedIndex] = '\\';
++escapedIndex;
default:
escapedName[escapedIndex] = inConstAttrName[originalIndex];
++escapedIndex;
break;
}
++originalIndex;
}
recTypeLen += 2;
cfStringRef = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("(|"));
numAttributes = 1;
nativeRecType = MapAttrToLDAPType( inConstAttrType, inConfigTableIndex, numAttributes );
if (nativeRecType == nil)
{
nativeRecType = new char[ 3 ];
::strcpy(nativeRecType, "cn");
}
while ( nativeRecType != nil )
{
if (bOnceThru)
{
if (useWellKnownRecType)
{
bOnceThru = false;
break;
}
offset = 0;
}
matchType = (unsigned long) (patternMatch);
switch (matchType)
{
case eDSStartsWith:
case eDSiStartsWith:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, nativeRecType, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,"=", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, escapedName, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,"*)", kCFStringEncodingMacRoman);
bOnceThru = true;
break;
case eDSEndsWith:
case eDSiEndsWith:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, nativeRecType, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,"=*", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, escapedName, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,")", kCFStringEncodingMacRoman);
bOnceThru = true;
break;
case eDSContains:
case eDSiContains:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, nativeRecType, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,"=*", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, escapedName, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,"*)", kCFStringEncodingMacRoman);
bOnceThru = true;
break;
case eDSWildCardPattern:
case eDSiWildCardPattern:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, nativeRecType, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,"=", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, inConstAttrName, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,")", kCFStringEncodingMacRoman);
bOnceThru = true;
break;
case eDSRegularExpression:
case eDSiRegularExpression:
CFStringAppendCString(cfStringRef, inConstAttrName, kCFStringEncodingMacRoman);
bOnceThru = true;
break;
case eDSExact:
case eDSiExact:
default:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, nativeRecType, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,"=", kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef, escapedName, kCFStringEncodingMacRoman);
CFStringAppendCString(cfStringRef,")", kCFStringEncodingMacRoman);
bOnceThru = true;
break;
}
if (nativeRecType != nil)
{
delete (nativeRecType);
nativeRecType = nil;
}
numAttributes++;
nativeRecType = MapAttrToLDAPType( inConstAttrType, inConfigTableIndex, numAttributes );
}
callocLength = CFStringGetLength(cfStringRef) + 2; queryFilter = (char *) calloc(1, callocLength);
if (offset == 3)
{
CFRange aRangeToDelete;
aRangeToDelete.location = 1;
aRangeToDelete.length = 2;
CFStringDelete(cfStringRef, aRangeToDelete);
CFStringGetCString( cfStringRef, queryFilter, callocLength, kCFStringEncodingMacRoman );
}
else
{
CFStringAppendCString(cfStringRef,")", kCFStringEncodingMacRoman);
CFStringGetCString( cfStringRef, queryFilter, callocLength, kCFStringEncodingMacRoman );
}
if (cfStringRef != nil)
{
CFRelease(cfStringRef);
cfStringRef = nil;
}
if (escapedName != nil)
{
free(escapedName);
escapedName = nil;
}
}
return (queryFilter);
}
sInt32 CLDAPPlugIn::GetDirNodeInfo ( sGetDirNodeInfo *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiOffset = 0;
uInt32 uiCntr = 1;
uInt32 uiAttrCnt = 0;
CAttributeList *inAttrList = nil;
char *pAttrName = nil;
char *pData = nil;
sLDAPContextData *pContext = nil;
sLDAPContextData *pAttrContext = nil;
CBuff outBuff;
CDataBuff *aRecData = nil;
CDataBuff *aAttrData = nil;
CDataBuff *aTmpData = nil;
try
{
if ( inData == nil ) throw( (sInt32)eMemoryError );
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
inAttrList = new CAttributeList( inData->fInDirNodeInfoTypeList );
if ( inAttrList == nil ) throw( (sInt32)eDSNullNodeInfoTypeList );
if (inAttrList->GetCount() == 0) throw( (sInt32)eDSEmptyNodeInfoTypeList );
siResult = outBuff.Initialize( inData->fOutDataBuff, true );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = outBuff.SetBuffType( 'Gdni' ); if ( siResult != eDSNoErr ) throw( siResult );
aRecData = new CDataBuff();
if ( aRecData == nil ) throw( (sInt32)eMemoryError );
aAttrData = new CDataBuff();
if ( aAttrData == nil ) throw( (sInt32)eMemoryError );
aTmpData = new CDataBuff();
if ( aTmpData == nil ) throw( (sInt32)eMemoryError );
aRecData->AppendShort( ::strlen( "dsAttrTypeStandard:DirectoryNodeInfo" ) );
aRecData->AppendString( (char *)"dsAttrTypeStandard:DirectoryNodeInfo" );
aRecData->AppendShort( ::strlen( "DirectoryNodeInfo" ) );
aRecData->AppendString( (char *)"DirectoryNodeInfo" );
while ( inAttrList->GetAttribute( uiCntr++, &pAttrName ) == eDSNoErr )
{
if ((::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, kDSNAttrNodePath ) == 0) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDSNAttrNodePath ) );
aTmpData->AppendString( kDSNAttrNodePath );
if ( inData->fInAttrInfoOnly == false )
{
aTmpData->AppendShort( 2 );
aTmpData->AppendLong( ::strlen( "LDAPv2" ) );
aTmpData->AppendString( (char *)"LDAPv2" );
char *tmpStr = nil;
if (pContext->fName != nil)
{
tmpStr = new char[1+::strlen(pContext->fName)];
::strcpy( tmpStr, pContext->fName );
}
else
{
tmpStr = new char[1+::strlen("Unknown Node Location")];
::strcpy( tmpStr, "Unknown Node Location" );
}
aTmpData->AppendLong( ::strlen( tmpStr ) );
aTmpData->AppendString( tmpStr );
delete( tmpStr );
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
if ( (::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, kDS1AttrReadOnlyNode ) == 0) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDS1AttrReadOnlyNode ) );
aTmpData->AppendString( kDS1AttrReadOnlyNode );
if ( inData->fInAttrInfoOnly == false )
{
aTmpData->AppendShort( 1 );
aTmpData->AppendLong( ::strlen( "ReadOnly" ) );
aTmpData->AppendString( "ReadOnly" );
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
if ((::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, kDSNAttrAuthMethod ) == 0) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDSNAttrAuthMethod ) );
aTmpData->AppendString( kDSNAttrAuthMethod );
if ( inData->fInAttrInfoOnly == false )
{
char *tmpStr = nil;
aTmpData->AppendShort( 4 );
tmpStr = new char[1+::strlen( kDSStdAuthCrypt )];
::strcpy( tmpStr, kDSStdAuthCrypt );
aTmpData->AppendLong( ::strlen( tmpStr ) );
aTmpData->AppendString( tmpStr );
delete( tmpStr );
tmpStr = nil;
tmpStr = new char[1+::strlen( kDSStdAuthClearText )];
::strcpy( tmpStr, kDSStdAuthClearText );
aTmpData->AppendLong( ::strlen( tmpStr ) );
aTmpData->AppendString( tmpStr );
delete( tmpStr );
tmpStr = nil;
tmpStr = new char[1+::strlen( kDSStdAuthNodeNativeClearTextOK )];
::strcpy( tmpStr, kDSStdAuthNodeNativeClearTextOK );
aTmpData->AppendLong( ::strlen( tmpStr ) );
aTmpData->AppendString( tmpStr );
delete( tmpStr );
tmpStr = nil;
tmpStr = new char[1+::strlen( kDSStdAuthNodeNativeNoClearText )];
::strcpy( tmpStr, kDSStdAuthNodeNativeNoClearText );
aTmpData->AppendLong( ::strlen( tmpStr ) );
aTmpData->AppendString( tmpStr );
delete( tmpStr );
tmpStr = nil;
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
if ((::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, "dsAttrTypeStandard:AccountName" ) == 0) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( "dsAttrTypeStandard:AccountName" ) );
aTmpData->AppendString( (char *)"dsAttrTypeStandard:AccountName" );
if ( inData->fInAttrInfoOnly == false )
{
char *tmpStr = nil;
if (pContext->authCallActive)
{
tmpStr = new char[1+::strlen(pContext->authAccountName)];
::strcpy( tmpStr, pContext->authAccountName );
}
if (tmpStr == nil)
{
tmpStr = new char[1+::strlen("No Account Name")];
::strcpy( tmpStr, "No Account Name" );
}
aTmpData->AppendShort( 1 );
aTmpData->AppendLong( ::strlen( tmpStr ) );
aTmpData->AppendString( tmpStr );
delete( tmpStr );
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
}
aRecData->AppendShort( uiAttrCnt );
if (uiAttrCnt > 0)
{
aRecData->AppendBlock( aAttrData->GetData(), aAttrData->GetLength() );
}
outBuff.AddData( aRecData->GetData(), aRecData->GetLength() );
inData->fOutAttrInfoCount = uiAttrCnt;
pData = outBuff.GetDataBlock( 1, &uiOffset );
if ( pData != nil )
{
pAttrContext = MakeContextData();
if ( pAttrContext == nil ) throw( (sInt32)eMemoryAllocError );
pAttrContext->fConfigTableIndex = pContext->fConfigTableIndex;
pAttrContext->offset = uiOffset + 61;
gRefTable->AddItem( inData->fOutAttrListRef, pAttrContext );
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( inAttrList != nil )
{
delete( inAttrList );
inAttrList = nil;
}
if ( aRecData != nil )
{
delete( aRecData );
aRecData = nil;
}
if ( aAttrData != nil )
{
delete( aAttrData );
aAttrData = nil;
}
if ( aTmpData != nil )
{
delete( aTmpData );
aTmpData = nil;
}
return( siResult );
}
sInt32 CLDAPPlugIn::OpenRecord ( sOpenRecord *inData )
{
sInt32 siResult = eDSNoErr;
tDataNodePtr pRecName = nil;
tDataNodePtr pRecType = nil;
char *pLDAPRecType = nil;
sLDAPContextData *pContext = nil;
sLDAPContextData *pRecContext = nil;
int ldapMsgId = 0;
char *queryFilter = nil;
LDAPMessage *result = nil;
int ldapReturnCode = 0;
int numRecTypes = 1;
bool bResultFound = false;
sLDAPConfigData *pConfig = nil;
int searchTO = 0;
try
{
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
pRecType = inData->fInRecType;
if ( pRecType == nil ) throw( (sInt32)eDSNullRecType );
pRecName = inData->fInRecName;
if ( pRecName == nil ) throw( (sInt32)eDSNullRecName );
if (pRecName->fBufferLength == 0) throw( (sInt32)eDSEmptyRecordNameList );
if (pRecType->fBufferLength == 0) throw( (sInt32)eDSEmptyRecordTypeList );
queryFilter = BuildLDAPQueryFilter((char *)kDSNAttrRecordName, pRecName->fBufferData, eDSExact, pContext->fConfigTableIndex, false);
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
if (( pContext->fConfigTableIndex < gConfigTableLen) && ( pContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( pContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
siResult = RebindTryProc(pContext);
if ( siResult != eDSNoErr ) throw( siResult );
numRecTypes = 1;
pLDAPRecType = MapRecToLDAPType( pRecType->fBufferData, pContext->fConfigTableIndex, numRecTypes );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while ( (pLDAPRecType != nil) && (!bResultFound) )
{
if ( (ldapMsgId = ldap_search( pContext->fHost, pLDAPRecType, LDAP_SCOPE_SUBTREE, queryFilter, NULL, 0) ) == -1 )
{
bResultFound = false;
}
else
{
bResultFound = true;
if (searchTO == 0)
{
ldapReturnCode = ldap_result(pContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(pContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
if (pLDAPRecType != nil)
{
delete (pLDAPRecType);
pLDAPRecType = nil;
}
numRecTypes++;
pLDAPRecType = MapRecToLDAPType( pRecType->fBufferData, pContext->fConfigTableIndex, numRecTypes );
}
if ( (bResultFound) && ( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) )
{
pRecContext = MakeContextData();
if ( pRecContext == nil ) throw( (sInt32)eMemoryAllocError );
pRecContext->pResult = result;
if (pContext->fName != nil)
{
pRecContext->fName = new char[1+::strlen(pContext->fName)];
::strcpy( pRecContext->fName, pContext->fName );
}
pRecContext->fType = 2;
pRecContext->msgId = ldapMsgId;
pRecContext->fHost = pContext->fHost;
pRecContext->fConfigTableIndex = pContext->fConfigTableIndex;
if (pRecType->fBufferData != nil)
{
pRecContext->fOpenRecordType = new char[1+::strlen(pRecType->fBufferData)];
::strcpy( pRecContext->fOpenRecordType, pRecType->fBufferData );
}
if (pRecName->fBufferData != nil)
{
pRecContext->fOpenRecordName = new char[1+::strlen(pRecName->fBufferData)];
::strcpy( pRecContext->fOpenRecordName, pRecName->fBufferData );
}
gRefTable->AddItem( inData->fOutRecRef, pRecContext );
} else if (ldapReturnCode == LDAP_TIMEOUT)
{
siResult = eDSServerTimeout;
if ( result != nil )
{
ldap_msgfree( result );
result = nil;
}
}
else
{
siResult = eDSRecordNotFound;
if ( result != nil )
{
ldap_msgfree( result );
result = nil;
}
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( pLDAPRecType != nil )
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
return( siResult );
}
sInt32 CLDAPPlugIn::CloseRecord ( sCloseRecord *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
try
{
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInRecRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
gRefTable->RemoveItem( inData->fInRecRef );
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPPlugIn::CloseAttributeList ( sCloseAttributeList *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInAttributeListRef );
if ( pContext != nil )
{
gRefTable->RemoveItem( inData->fInAttributeListRef );
}
else
{
siResult = eDSInvalidAttrListRef;
}
return( siResult );
}
sInt32 CLDAPPlugIn::CloseAttributeValueList ( sCloseAttributeValueList *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInAttributeValueListRef );
if ( pContext != nil )
{
gRefTable->RemoveItem( inData->fInAttributeValueListRef );
}
else
{
siResult = eDSInvalidAttrValueRef;
}
return( siResult );
}
sInt32 CLDAPPlugIn::GetRecRefInfo ( sGetRecRefInfo *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiRecSize = 0;
tRecordEntry *pRecEntry = nil;
sLDAPContextData *pContext = nil;
char *refType = nil;
uInt32 uiOffset = 0;
char *refName = nil;
try
{
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInRecRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
if ( pContext->fOpenRecordType != nil)
{
refType = new char[1+::strlen(pContext->fOpenRecordType)];
::strcpy( refType, pContext->fOpenRecordType );
}
else {
refType = new char[1+::strlen("Record Type Unknown")];
::strcpy( refType, "Record Type Unknown" );
}
if ( pContext->fOpenRecordName != nil)
{
refName = new char[1+::strlen(pContext->fOpenRecordName)];
::strcpy( refName, pContext->fOpenRecordName );
}
else {
refName = new char[1+::strlen("Record Name Unknown")];
::strcpy( refName, "Record Name Unknown" );
}
uiRecSize = sizeof( tRecordEntry ) + ::strlen( refType ) + ::strlen( refName ) + 4 + kBuffPad;
pRecEntry = (tRecordEntry *)::calloc( 1, uiRecSize );
pRecEntry->fRecordNameAndType.fBufferSize = ::strlen( refType ) + ::strlen( refName ) + 4 + kBuffPad;
pRecEntry->fRecordNameAndType.fBufferLength = ::strlen( refType ) + ::strlen( refName ) + 4;
uiOffset = 0;
uInt16 strLen = 0;
strLen = ::strlen( refName );
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, &strLen, 2);
uiOffset += 2;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, refName, strLen);
uiOffset += strLen;
strLen = ::strlen( refType );
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, &strLen, 2);
uiOffset += 2;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, refType, strLen);
uiOffset += strLen;
inData->fOutRecInfo = pRecEntry;
}
catch( sInt32 err )
{
siResult = err;
}
if (refType != nil)
{
delete( refType );
refType = nil;
}
if (refName != nil)
{
delete( refName );
refName = nil;
}
return( siResult );
}
sInt32 CLDAPPlugIn::GetRecAttribInfo ( sGetRecAttribInfo *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiTypeLen = 0;
uInt32 uiDataLen = 0;
tDataNodePtr pAttrType = nil;
char *pLDAPAttrType = nil;
tAttributeEntryPtr pOutAttrEntry = nil;
sLDAPContextData *pContext = nil;
LDAPMessage *result = nil;
BerElement *ber;
struct berval **bValues;
char *pAttr = nil;
int numAttributes = 1;
bool bTypeFound = false;
int valCount = 0;
try
{
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInRecRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
pAttrType = inData->fInAttrType;
if ( pAttrType == nil ) throw( (sInt32)eDSEmptyAttributeType );
result = pContext->pResult;
if ( result != nil )
{
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pAttrType->fBufferData, pContext->fConfigTableIndex, numAttributes );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
bTypeFound = false;
while ( pLDAPAttrType != nil )
{
for ( pAttr = ldap_first_attribute (pContext->fHost, result, &ber );
pAttr != NULL; pAttr = ldap_next_attribute(pContext->fHost, result, ber ) )
{
if (::strcmp( pAttr, pLDAPAttrType ) == 0) {
if (!bTypeFound)
{
uiTypeLen = ::strlen( pAttrType->fBufferData );
pOutAttrEntry = (tAttributeEntry *)::calloc( 1, sizeof( tAttributeEntry ) + uiTypeLen + kBuffPad );
pOutAttrEntry->fAttributeSignature.fBufferSize = uiTypeLen;
pOutAttrEntry->fAttributeSignature.fBufferLength = uiTypeLen;
::memcpy( pOutAttrEntry->fAttributeSignature.fBufferData, pAttrType->fBufferData, uiTypeLen );
bTypeFound = true;
valCount = 0;
uiDataLen = 0;
}
if (( bValues = ldap_get_values_len (pContext->fHost, result, pAttr )) != NULL)
{
for (int ii = 0; bValues[ii] != NULL; ii++ )
valCount++;
for (int i = 0; bValues[i] != NULL; i++ )
{
uiDataLen += bValues[i]->bv_len;
} ldap_value_free_len(bValues);
}
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
break;
}
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
}
if (ber != nil)
{
ber_free( ber, 0 );
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pAttrType->fBufferData, pContext->fConfigTableIndex, numAttributes );
}
if ( pOutAttrEntry == nil )
{
inData->fOutAttrInfoPtr = nil;
throw( (sInt32)eDSAttributeNotFound);
}
pOutAttrEntry->fAttributeValueCount = valCount;
pOutAttrEntry->fAttributeValueMaxSize = 255;
pOutAttrEntry->fAttributeDataSize = uiDataLen;
inData->fOutAttrInfoPtr = pOutAttrEntry;
} else
{
throw( (sInt32)eDSRecordNotFound); }
}
catch( sInt32 err )
{
siResult = err;
}
if (pLDAPAttrType != nil)
{
delete( pLDAPAttrType );
pLDAPAttrType = nil;
}
return( siResult );
}
sInt32 CLDAPPlugIn::GetRecAttrValueByIndex ( sGetRecordAttributeValueByIndex *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiDataLen = 0;
tDataNodePtr pAttrType = nil;
char *pLDAPAttrType = nil;
tAttributeValueEntryPtr pOutAttrValue = nil;
sLDAPContextData *pContext = nil;
LDAPMessage *result = nil;
BerElement *ber;
struct berval **bValues;
char *pAttr = nil;
char *pAttrVal = nil;
unsigned long valCount = 0;
bool bFoundIt = false;
int numAttributes = 1;
try
{
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInRecRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
pAttrType = inData->fInAttrType;
if ( pAttrType == nil ) throw( (sInt32)eDSEmptyAttributeType );
result = pContext->pResult;
if ( result != nil )
{
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pAttrType->fBufferData, pContext->fConfigTableIndex, numAttributes );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
bFoundIt = false;
while ( ( pLDAPAttrType != nil ) && (!bFoundIt) )
{
for ( pAttr = ldap_first_attribute (pContext->fHost, result, &ber );
pAttr != NULL; pAttr = ldap_next_attribute(pContext->fHost, result, ber ) )
{
if (::strcmp( pAttr, pLDAPAttrType ) == 0) {
if (( bValues = ldap_get_values_len (pContext->fHost, result, pAttr )) != NULL)
{
for (int i = 0; bValues[i] != NULL; i++ )
{
valCount++;
if (valCount == inData->fInAttrValueIndex)
{
uiDataLen = bValues[i]->bv_len;
pAttrVal = new char[uiDataLen+1];
::strcpy(pAttrVal,bValues[i]->bv_val);
pOutAttrValue = (tAttributeValueEntry *)::calloc( 1, sizeof( tAttributeValueEntry ) + uiDataLen + kBuffPad );
pOutAttrValue->fAttributeValueData.fBufferSize = uiDataLen;
pOutAttrValue->fAttributeValueData.fBufferLength = uiDataLen;
if ( pAttrVal != nil )
{
pOutAttrValue->fAttributeValueID = CalcCRC( pAttrVal );
::memcpy( pOutAttrValue->fAttributeValueData.fBufferData, pAttrVal, uiDataLen );
}
bFoundIt = true;
break;
} } ldap_value_free_len(bValues);
}
}
if (bFoundIt)
{
inData->fOutEntryPtr = pOutAttrValue;
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
break; }
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
}
if (ber != nil)
{
ber_free( ber, 0 );
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pAttrType->fBufferData, pContext->fConfigTableIndex, numAttributes );
}
if (!bFoundIt)
{
if (valCount < inData->fInAttrValueIndex)
{
siResult = eDSIndexOutOfRange;
}
else
{
siResult = eDSAttributeNotFound;
}
}
} else
{
throw( (sInt32)eDSRecordNotFound); }
if (pAttrVal != nil)
{
delete( pAttrVal );
pAttrVal = nil;
}
if (pLDAPAttrType != nil)
{
delete( pLDAPAttrType );
pLDAPAttrType = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
char* CLDAPPlugIn::GetNextStdAttrType ( uInt32 inConfigTableIndex, int inIndex )
{
char *outResult = nil;
sLDAPConfigData *pConfig = nil;
sMapTuple *pMapTuple = nil;
int countStd = 0;
bool foundStd = false;
if (inIndex > 0)
{
if (( inConfigTableIndex < gConfigTableLen) && ( inConfigTableIndex >= 0 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inConfigTableIndex );
if (pConfig != nil)
{
pMapTuple = pConfig->pAttributeMapTuple;
}
}
if ( pMapTuple == nil )
{
pMapTuple = pStdAttributeMapTuple;
}
if ( pMapTuple != nil )
{
countStd = 0;
while ((pMapTuple != nil) && !(foundStd))
{
if (pMapTuple->fStandard != nil)
{
countStd++;
if (inIndex == countStd)
{
outResult = new char[1+::strlen( pMapTuple->fStandard )];
::strcpy( outResult, pMapTuple->fStandard );
foundStd = true;
}
} pMapTuple = pMapTuple->pNext;
} }
}
return( outResult );
}
sInt32 CLDAPPlugIn::DoAttributeValueSearch ( sDoAttrValueSearchWithData *inData )
{
sInt32 siResult = eDSNoErr;
bool bAttribOnly = false;
uInt32 uiCount = 0;
uInt32 uiTotal = 0;
CAttributeList *cpRecTypeList = nil;
CAttributeList *cpAttrTypeList = nil;
char *pSearchStr = nil;
char *pRecType = nil;
char *pAttrType = nil;
char *pLDAPRecType = nil;
tDirPatternMatch pattMatch = eDSExact;
sLDAPContextData *pContext = nil;
CBuff *outBuff = nil;
tDataList *pTmpDataList = nil;
int numRecTypes = 1;
bool bBuffFull = false;
bool separateRecTypes = false;
uInt32 countDownRecTypes = 0;
try
{
if ( inData == nil ) throw( (sInt32)eMemoryError );
if ( inData->fOutDataBuff == nil ) throw( (sInt32)eDSEmptyBuffer );
if (inData->fOutDataBuff->fBufferSize == 0) throw( (sInt32)eDSEmptyBuffer );
if ( inData->fInRecTypeList == nil ) throw( (sInt32)eDSEmptyRecordTypeList );
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
if ( inData->fIOContinueData != nil )
{
if ( inData->fIOContinueData != pContext )
{
throw( (sInt32)eDSInvalidContext );
}
}
else
{
pContext->fRecTypeIndex = 1;
pContext->fAttrIndex = 1;
pContext->fTotalRecCount = 0;
pContext->fLimitRecSearch = 0;
if (inData->fOutMatchRecordCount >= 0)
{
pContext->fLimitRecSearch = inData->fOutMatchRecordCount;
}
}
inData->fIOContinueData = nil;
inData->fOutMatchRecordCount = 0;
outBuff = new CBuff();
if ( outBuff == nil ) throw( (sInt32)eMemoryError );
siResult = outBuff->Initialize( inData->fOutDataBuff, true );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = outBuff->GetBuffStatus();
if ( siResult != eDSNoErr ) throw( siResult );
siResult = outBuff->SetBuffType( 'StdA' );
if ( siResult != eDSNoErr ) throw( siResult );
cpRecTypeList = new CAttributeList( inData->fInRecTypeList );
if ( cpRecTypeList == nil ) throw( (sInt32)eDSEmptyRecordTypeList );
countDownRecTypes = cpRecTypeList->GetCount() - pContext->fRecTypeIndex + 1;
if (cpRecTypeList->GetCount() == 0) throw( (sInt32)eDSEmptyRecordTypeList );
pAttrType = inData->fInAttrType->fBufferData;
if ( pAttrType == nil ) throw( (sInt32)eDSEmptyAttributeType );
pSearchStr = inData->fInPatt2Match->fBufferData;
if ( pSearchStr == nil ) throw( (sInt32)eDSEmptyPattern2Match );
pattMatch = inData->fInPattMatchType;
if ( inData->fType == kDoAttributeValueSearchWithData )
{
cpAttrTypeList = new CAttributeList( inData->fInAttrTypeRequestList );
if ( cpAttrTypeList == nil ) throw( (sInt32)eDSEmptyAttributeTypeList );
if (cpAttrTypeList->GetCount() == 0) throw( (sInt32)eDSEmptyAttributeTypeList );
bAttribOnly = inData->fInAttrInfoOnly;
}
else
{
pTmpDataList = dsBuildListFromStringsPriv( kDSAttributesAll, nil );
if ( pTmpDataList != nil )
{
cpAttrTypeList = new CAttributeList( pTmpDataList );
if ( cpAttrTypeList == nil ) throw( (sInt32)eDSEmptyAttributeTypeList );
if (cpAttrTypeList->GetCount() == 0) throw( (sInt32)eDSEmptyAttributeTypeList );
}
}
while ((( cpRecTypeList->GetAttribute( pContext->fRecTypeIndex, &pRecType ) == eDSNoErr ) && (!bBuffFull)) && (!separateRecTypes))
{
numRecTypes = 1;
pLDAPRecType = MapRecToLDAPType( pRecType, pContext->fConfigTableIndex, numRecTypes );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while (( pLDAPRecType != nil ) && (!bBuffFull))
{
bBuffFull = false;
if ( (::strcmp( pAttrType, kDSAttributesAll ) == 0 ) ||
(::strcmp( pAttrType, kDSAttributesStandardAll ) == 0 ) ||
(::strcmp( pAttrType, kDSAttributesNativeAll ) == 0 ) )
{
siResult = FindAllRecords( pSearchStr, pRecType, pLDAPRecType, pattMatch, cpAttrTypeList, pContext, bAttribOnly, outBuff, uiCount );
}
else
{
siResult = FindTheseRecords( pAttrType, pSearchStr, pRecType, pLDAPRecType, pattMatch, cpAttrTypeList, pContext, bAttribOnly, outBuff, uiCount );
}
if ( siResult == CBuff::kBuffFull )
{
bBuffFull = true;
inData->fIOContinueData = pContext;
if (uiCount == 0)
{
throw( (sInt32)eDSBufferTooSmall );
}
uiTotal += uiCount;
inData->fOutMatchRecordCount = uiTotal;
outBuff->SetLengthToSize();
siResult = eDSNoErr;
}
else if ( siResult == eDSNoErr )
{
uiTotal += uiCount;
}
if (pLDAPRecType != nil)
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if (!bBuffFull)
{
numRecTypes++;
pLDAPRecType = MapRecToLDAPType( pRecType, pContext->fConfigTableIndex, numRecTypes );
}
}
if (!bBuffFull)
{
pRecType = nil;
pContext->fRecTypeIndex++;
pContext->msgId = 0;
separateRecTypes = true;
inData->fIOContinueData = pContext;
siResult = eDSNoErr;
countDownRecTypes--;
if (countDownRecTypes == 0)
{
inData->fIOContinueData = nil;
}
}
}
if (( siResult == eDSNoErr ) & (!bBuffFull))
{
if ( uiTotal == 0 )
{
outBuff->ClearBuff();
}
else
{
outBuff->SetLengthToSize();
}
inData->fOutMatchRecordCount = uiTotal;
}
}
catch( sInt32 err )
{
siResult = err;
}
if (pLDAPRecType != nil)
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if ( cpRecTypeList != nil )
{
delete( cpRecTypeList );
cpRecTypeList = nil;
}
if ( cpAttrTypeList != nil )
{
delete( cpAttrTypeList );
cpAttrTypeList = nil;
}
if ( pTmpDataList != nil )
{
dsDataListDeallocatePriv( pTmpDataList );
free(pTmpDataList);
pTmpDataList = nil;
}
if ( outBuff != nil )
{
delete( outBuff );
outBuff = nil;
}
return( siResult );
}
bool CLDAPPlugIn::DoTheseAttributesMatch ( sLDAPContextData *inContext,
char *inAttrName,
tDirPatternMatch pattMatch,
LDAPMessage *inResult)
{
char *pAttr = nil;
char *pVal = nil;
BerElement *ber;
struct berval **bValues;
bool bFoundMatch = false;
for ( pAttr = ldap_first_attribute (inContext->fHost, inResult, &ber );
pAttr != NULL; pAttr = ldap_next_attribute(inContext->fHost, inResult, ber ) )
{
if (( bValues = ldap_get_values_len (inContext->fHost, inResult, pAttr )) != NULL)
{
for (int i = 0; bValues[i] != NULL; i++ )
{
pVal = (char *) calloc(1,bValues[i]->bv_len + 1);
memcpy(pVal, bValues[i]->bv_val, bValues[i]->bv_len);
if (DoesThisMatch(pVal, inAttrName, pattMatch))
{
bFoundMatch = true;
free(pVal);
pVal = nil;
break;
}
else
{
free(pVal);
pVal = nil;
}
} ldap_value_free_len(bValues);
if (bFoundMatch)
{
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
break;
}
}
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
}
if (ber != nil)
{
ber_free( ber, 0 );
}
return( bFoundMatch );
}
bool CLDAPPlugIn::DoesThisMatch ( const char *inString,
const char *inPatt,
tDirPatternMatch inPattMatch )
{
const char *p = nil;
bool bMatched = false;
char *string1;
char *string2;
uInt32 length1 = 0;
uInt32 length2 = 0;
uInt32 uMatch = 0;
uInt16 usIndex = 0;
if ( (inString == nil) || (inPatt == nil) )
{
return( false );
}
length1 = strlen(inString);
length2 = strlen(inPatt);
string1 = new char[length1 + 1];
string2 = new char[length2 + 1];
if ( (inPattMatch >= eDSExact) && (inPattMatch <= eDSRegularExpression) )
{
strcpy(string1,inString);
strcpy(string2,inPatt);
}
else
{
p = inString;
for ( usIndex = 0; usIndex < length1; usIndex++ )
{
string1[usIndex] = toupper( *p );
p++;
}
p = inPatt;
for ( usIndex = 0; usIndex < length2; usIndex++ )
{
string2[usIndex] = toupper( *p );
p++;
}
}
uMatch = (uInt32) inPattMatch;
switch ( uMatch )
{
case eDSExact:
case eDSiExact:
{
if ( strcmp( string1, string2 ) == 0 )
{
bMatched = true;
}
}
break;
case eDSStartsWith:
case eDSiStartsWith:
{
if ( strncmp( string1, string2, length2 ) == 0 )
{
bMatched = true;
}
}
break;
case eDSEndsWith:
case eDSiEndsWith:
{
if ( length1 >= length2 )
{
if ( strcmp( string1 + length1 - length2, string2 ) == 0 )
{
bMatched = true;
}
}
}
break;
case eDSContains:
case eDSiContains:
{
if ( length1 >= length2 )
{
if ( strstr( string1, string2 ) != nil )
{
bMatched = true;
}
}
}
break;
case eDSLessThan:
case eDSiLessThan:
{
if ( strcmp( string1, string2 ) < 0 )
{
bMatched = true;
}
}
break;
case eDSGreaterThan:
case eDSiGreaterThan:
{
if ( strcmp( string1, string2 ) > 0 )
{
bMatched = true;
}
}
break;
case eDSLessEqual:
case eDSiLessEqual:
{
if ( strcmp( string1, string2 ) <= 0 )
{
bMatched = true;
}
}
break;
case eDSGreaterEqual:
case eDSiGreaterEqual:
{
if ( strcmp( string1, string2 ) >= 0 )
{
bMatched = true;
}
}
break;
case eDSAnyMatch:
default:
break;
}
if (string1 != nil)
{
delete(string1);
}
if (string2 != nil)
{
delete(string2);
}
return( bMatched );
}
sInt32 CLDAPPlugIn::FindAllRecords ( char *inConstAttrName,
char *inConstRecType,
char *inNativeRecType,
tDirPatternMatch patternMatch,
CAttributeList *inAttrTypeList,
sLDAPContextData *inContext,
bool inAttrOnly,
CBuff *inBuff,
uInt32 &outRecCount )
{
sInt32 siResult = eDSNoErr;
sInt32 siValCnt = 0;
int ldapReturnCode = 0;
int ldapMsgId = 0;
bool bufferFull = false;
LDAPMessage *result = nil;
char *recName = nil;
sLDAPConfigData *pConfig = nil;
int searchTO = 0;
bool bFoundMatch = false;
CDataBuff *aRecData = nil;
CDataBuff *aAttrData = nil;
outRecCount = 0;
try
{
if (inContext == nil ) throw( (sInt32)eDSInvalidContext);
aRecData = new CDataBuff();
if ( aRecData == nil ) throw( (sInt32)eMemoryError );
aAttrData = new CDataBuff();
if ( aAttrData == nil ) throw( (sInt32)eMemoryError );
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
siResult = RebindTryProc(inContext);
if ( siResult != eDSNoErr ) throw( siResult );
if (inContext->msgId == 0)
{
if ( (ldapMsgId = ldap_search( inContext->fHost, inNativeRecType, LDAP_SCOPE_SUBTREE, (char *)"(objectclass=*)", NULL, 0) ) == -1 )
{
throw( (sInt32)eDSNoErr); }
inContext->msgId = ldapMsgId;
} else
{
ldapMsgId = inContext->msgId;
}
if ( (inContext->fTotalRecCount < inContext->fLimitRecSearch) || (inContext->fLimitRecSearch == 0) )
{
if (inContext->pResult != nil)
{
result = inContext->pResult;
ldapReturnCode = LDAP_RES_SEARCH_ENTRY;
}
else
{
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
}
while ( ( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) && !(bufferFull) &&
( (inContext->fTotalRecCount < inContext->fLimitRecSearch) || (inContext->fLimitRecSearch == 0) ) )
{
bFoundMatch = false;
if ( DoTheseAttributesMatch(inContext, inConstAttrName, patternMatch, result) )
{
bFoundMatch = true;
aRecData->Clear();
if ( inConstRecType != nil )
{
aRecData->AppendShort( ::strlen( inConstRecType ) );
aRecData->AppendString( inConstRecType );
} else
{
aRecData->AppendShort( ::strlen( "Record Type Unknown" ) );
aRecData->AppendString( "Record Type Unknown" );
}
recName = GetRecordName( result, inContext, siResult );
if ( siResult != eDSNoErr ) throw( siResult );
if ( recName != nil )
{
aRecData->AppendShort( ::strlen( recName ) );
aRecData->AppendString( recName );
delete ( recName );
recName = nil;
}
else
{
aRecData->AppendShort( ::strlen( "Record Name Unknown" ) );
aRecData->AppendString( "Record Name Unknown" );
}
aAttrData->Clear();
siResult = GetTheseAttributes( inAttrTypeList, result, inAttrOnly, inContext, siValCnt, aAttrData );
if ( siResult != eDSNoErr ) throw( siResult );
if ( siValCnt == 0 )
{
aRecData->AppendShort( 0 );
}
else
{
aRecData->AppendShort( siValCnt );
aRecData->AppendBlock( aAttrData->GetData(), aAttrData->GetLength() );
}
siResult = inBuff->AddData( aRecData->GetData(), aRecData->GetLength() );
}
if (siResult == CBuff::kBuffFull)
{
bufferFull = true;
inContext->pResult = result;
}
else if ( siResult == eDSNoErr )
{
ldap_msgfree( result );
result = nil;
if (bFoundMatch)
{
outRecCount++; inContext->fTotalRecCount++;
}
inContext->pResult = nil;
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
else
{
inContext->pResult = nil;
throw( (sInt32)eDSInvalidBuffFormat);
}
}
if (ldapReturnCode == LDAP_TIMEOUT)
{
siResult = eDSServerTimeout;
}
if ( (result != inContext->pResult) && (result != nil) )
{
ldap_msgfree( result );
result = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( aRecData != nil )
{
delete( aRecData );
aRecData = nil;
}
if ( aAttrData != nil )
{
delete( aAttrData );
aAttrData = nil;
}
return( siResult );
}
sInt32 CLDAPPlugIn::FindTheseRecords ( char *inConstAttrType,
char *inConstAttrName,
char *inConstRecType,
char *inNativeRecType,
tDirPatternMatch patternMatch,
CAttributeList *inAttrTypeList,
sLDAPContextData *inContext,
bool inAttrOnly,
CBuff *inBuff,
uInt32 &outRecCount )
{
sInt32 siResult = eDSNoErr;
sInt32 siValCnt = 0;
int ldapReturnCode = 0;
int ldapMsgId = 0;
bool bufferFull = false;
LDAPMessage *result = nil;
char *recName = nil;
char *queryFilter = nil;
sLDAPConfigData *pConfig = nil;
int searchTO = 0;
CDataBuff *aRecData = nil;
CDataBuff *aAttrData = nil;
queryFilter = BuildLDAPQueryFilter(inConstAttrType, inConstAttrName, patternMatch, inContext->fConfigTableIndex, false);
outRecCount = 0;
try
{
if (inContext == nil ) throw( (sInt32)eDSInvalidContext);
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
aRecData = new CDataBuff();
if ( aRecData == nil ) throw( (sInt32)eMemoryError );
aAttrData = new CDataBuff();
if ( aAttrData == nil ) throw( (sInt32)eMemoryError );
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
siResult = RebindTryProc(inContext);
if ( siResult != eDSNoErr ) throw( siResult );
if (inContext->msgId == 0)
{
if ( (ldapMsgId = ldap_search( inContext->fHost, inNativeRecType, LDAP_SCOPE_SUBTREE, queryFilter, NULL, 0) ) == -1 )
{
throw( (sInt32)eDSNoErr); }
inContext->msgId = ldapMsgId;
} else
{
ldapMsgId = inContext->msgId;
}
if ( (inContext->fTotalRecCount < inContext->fLimitRecSearch) || (inContext->fLimitRecSearch == 0) )
{
if (inContext->pResult != nil)
{
result = inContext->pResult;
ldapReturnCode = LDAP_RES_SEARCH_ENTRY;
}
else
{
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
}
while ( ( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) && !(bufferFull) &&
( (inContext->fTotalRecCount < inContext->fLimitRecSearch) || (inContext->fLimitRecSearch == 0) ) )
{
aRecData->Clear();
if ( inConstRecType != nil )
{
aRecData->AppendShort( ::strlen( inConstRecType ) );
aRecData->AppendString( inConstRecType );
}
else
{
aRecData->AppendShort( ::strlen( "Record Type Unknown" ) );
aRecData->AppendString( "Record Type Unknown" );
}
recName = GetRecordName( result, inContext, siResult );
if ( siResult != eDSNoErr ) throw( siResult );
if ( recName != nil )
{
aRecData->AppendShort( ::strlen( recName ) );
aRecData->AppendString( recName );
delete ( recName );
recName = nil;
}
else
{
aRecData->AppendShort( ::strlen( "Record Name Unknown" ) );
aRecData->AppendString( "Record Name Unknown" );
}
aAttrData->Clear();
siResult = GetTheseAttributes( inAttrTypeList, result, inAttrOnly, inContext, siValCnt, aAttrData );
if ( siResult != eDSNoErr ) throw( siResult );
if ( siValCnt == 0 )
{
aRecData->AppendShort( 0 );
}
else
{
aRecData->AppendShort( siValCnt );
aRecData->AppendBlock( aAttrData->GetData(), aAttrData->GetLength() );
}
siResult = inBuff->AddData( aRecData->GetData(), aRecData->GetLength() );
if (siResult == CBuff::kBuffFull)
{
bufferFull = true;
inContext->msgId = ldapMsgId;
inContext->pResult = result;
}
else if ( siResult == eDSNoErr )
{
ldap_msgfree( result );
inContext->msgId = 0;
outRecCount++; inContext->fTotalRecCount++;
inContext->pResult = nil;
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
else
{
inContext->msgId = 0;
inContext->pResult = nil;
throw( (sInt32)eDSInvalidBuffFormat);
}
}
if (ldapReturnCode == LDAP_TIMEOUT)
{
siResult = eDSServerTimeout;
}
if ( (result != inContext->pResult) && (result != nil) )
{
ldap_msgfree( result );
result = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
if ( aRecData != nil )
{
delete( aRecData );
aRecData = nil;
}
if ( aAttrData != nil )
{
delete( aAttrData );
aAttrData = nil;
}
return( siResult );
}
sInt32 CLDAPPlugIn::DoAuthentication ( sDoDirNodeAuth *inData )
{
sInt32 siResult = noErr;
UInt32 uiAuthMethod = 0;
sLDAPContextData *pContext = nil;
try
{
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
siResult = GetAuthMethod( inData->fInAuthMethod, &uiAuthMethod );
if ( siResult == noErr )
{
switch( uiAuthMethod )
{
case kAuthCrypt:
case kAuthNativeNoClearText:
siResult = DoUnixCryptAuth( pContext, inData->fInAuthStepData );
break;
case kAuthNativeClearTextOK:
if ( inData->fInDirNodeAuthOnlyFlag == true )
{
siResult = DoUnixCryptAuth( pContext, inData->fInAuthStepData );
if ( siResult == eDSNoErr )
{
if ( inData->fOutAuthStepDataResponse->fBufferSize > ::strlen( kDSStdAuthCrypt ) )
{
::strcpy( inData->fOutAuthStepDataResponse->fBufferData, kDSStdAuthCrypt );
}
}
}
if ( (siResult != eDSNoErr) || (inData->fInDirNodeAuthOnlyFlag == false) )
{
siResult = DoClearTextAuth( pContext, inData->fInAuthStepData, inData->fInDirNodeAuthOnlyFlag );
if ( siResult == eDSNoErr )
{
if ( inData->fOutAuthStepDataResponse->fBufferSize > ::strlen( kDSStdAuthClearText ) )
{
::strcpy( inData->fOutAuthStepDataResponse->fBufferData, kDSStdAuthClearText );
}
}
}
break;
case kAuthClearText:
siResult = DoClearTextAuth( pContext, inData->fInAuthStepData, inData->fInDirNodeAuthOnlyFlag );
if ( siResult == eDSNoErr )
{
if ( inData->fOutAuthStepDataResponse->fBufferSize > ::strlen( kDSStdAuthClearText ) )
{
::strcpy( inData->fOutAuthStepDataResponse->fBufferData, kDSStdAuthClearText );
}
}
break;
default:
siResult = eDSAuthMethodNotSupported;
break;
}
}
}
catch( sInt32 err )
{
siResult = err;
}
inData->fResult = siResult;
return( siResult );
}
sInt32 CLDAPPlugIn::GetAuthMethod ( tDataNode *inData, uInt32 *outAuthMethod )
{
sInt32 siResult = noErr;
char *p = nil;
if ( inData == nil )
{
*outAuthMethod = kAuthUnknowMethod;
return( eDSAuthParameterError );
}
p = (char *)inData->fBufferData;
CShared::LogIt( 0x0F, "LDAP PlugIn: Attempting use of authentication method %s", p );
if ( ::strcmp( p, kDSStdAuthClearText ) == 0 )
{
*outAuthMethod = kAuthClearText;
}
else if ( ::strcmp( p, kDSStdAuthNodeNativeClearTextOK ) == 0 )
{
*outAuthMethod = kAuthNativeClearTextOK;
}
else if ( ::strcmp( p, kDSStdAuthNodeNativeNoClearText ) == 0 )
{
*outAuthMethod = kAuthNativeNoClearText;
}
else if ( ::strcmp( p, kDSStdAuthCrypt ) == 0 )
{
*outAuthMethod = kAuthCrypt;
}
else
{
*outAuthMethod = kAuthUnknowMethod;
siResult = eDSAuthMethodNotSupported;
}
return( siResult );
}
sInt32 CLDAPPlugIn::DoUnixCryptAuth ( sLDAPContextData *inContext, tDataBuffer *inAuthData )
{
sInt32 siResult = eDSAuthFailed;
sInt32 bindResult = eDSNoErr;
char *pData = nil;
uInt32 offset = 0;
uInt32 buffSize = 0;
uInt32 buffLen = 0;
char *userName = nil;
sInt32 nameLen = 0;
char *pwd = nil;
sInt32 pwdLen = 0;
char *cryptPwd = nil;
char *pLDAPRecType = nil;
int ldapMsgId = 0;
char *queryFilter = nil;
LDAPMessage *result = nil;
LDAPMessage *entry = nil;
char *attr = nil;
char **vals = nil;
BerElement *ber = nil;
int ldapReturnCode = 0;
int numRecTypes = 1;
bool bResultFound = false;
sLDAPConfigData *pConfig = nil;
char **attrs = nil;
int searchTO = 0;
try
{
if ( inContext == nil ) throw( (sInt32)eDSBadContextData );
if ( inAuthData == nil ) throw( (sInt32)eDSNullDataBuff );
pData = inAuthData->fBufferData;
if ( pData == nil ) throw( (sInt32)eDSNullDataBuff );
buffSize = inAuthData->fBufferSize;
buffLen = inAuthData->fBufferLength;
if (buffLen > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
if ( (sInt32)(2 * sizeof( unsigned long ) + 1) > (sInt32)(buffLen - offset) ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &nameLen, pData, sizeof( unsigned long ) );
if (nameLen == 0) throw( (sInt32)eDSInvalidBuffFormat );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
userName = (char *)::calloc(1, nameLen + 1);
if ( userName == nil ) throw( (sInt32)eMemoryError );
if ( (sInt32)nameLen > (sInt32)(buffLen - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( userName, pData, nameLen );
pData += nameLen;
offset += nameLen;
if ( (sInt32)sizeof( unsigned long ) > (sInt32)(buffLen - offset) ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &pwdLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
pwd = (char *)::calloc(1, pwdLen + 1);
if ( pwd == nil ) throw( (sInt32)eMemoryError );
if ( (sInt32)pwdLen > (sInt32)(buffLen - offset) ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( pwd, pData, pwdLen );
queryFilter = BuildLDAPQueryFilter((char *)kDSNAttrRecordName, userName, eDSExact, inContext->fConfigTableIndex, false);
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
attrs = MapAttrToLDAPTypeArray( kDS1AttrPassword, inContext->fConfigTableIndex );
CShared::LogIt( 0x0F, "LDAP PlugIn: Attempting Crypt Authentication" );
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
bindResult = RebindTryProc(inContext);
if ( bindResult != eDSNoErr ) throw( bindResult );
numRecTypes = 1;
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while ( (pLDAPRecType != nil) && (!bResultFound) )
{
if ( (ldapMsgId = ldap_search( inContext->fHost, pLDAPRecType, LDAP_SCOPE_SUBTREE, queryFilter, attrs, 0) ) == -1 )
{
bResultFound = false;
}
else
{
bResultFound = true;
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
if (pLDAPRecType != nil)
{
delete (pLDAPRecType);
pLDAPRecType = nil;
}
numRecTypes++;
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes );
}
if ( (bResultFound) && ( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) )
{
entry = ldap_first_entry( inContext->fHost, result );
if ( entry != nil )
{
attr = ldap_first_attribute( inContext->fHost, entry, &ber );
if ( attr != nil )
{
vals = ldap_get_values( inContext->fHost, entry, attr );
if ( vals != nil )
{
if ( vals[0] != nil )
{
cryptPwd = vals[0];
}
else
{
cryptPwd = (char *)""; }
if (::strncasecmp(cryptPwd,"{crypt}",7) == 0)
{
cryptPwd = cryptPwd + 7;
}
if (::strcmp(cryptPwd,"") != 0)
{
char salt[ 9 ];
char hashPwd[ 32 ];
salt[ 0 ] = cryptPwd[0];
salt[ 1 ] = cryptPwd[1];
salt[ 2 ] = '\0';
::memset( hashPwd, 0, 32 );
::strcpy( hashPwd, ::crypt( pwd, salt ) );
siResult = eDSAuthFailed;
if ( ::strcmp( hashPwd, cryptPwd ) == 0 )
{
siResult = eDSNoErr;
}
}
else {
if ( ::strcmp(pwd,"") == 0 )
{
siResult = eDSNoErr;
}
}
ldap_value_free( vals );
vals = nil;
}
ldap_memfree( attr );
attr = nil;
}
if ( ber != nil )
{
ber_free( ber, 0 );
}
ldap_abandon( inContext->fHost, ldapMsgId ); }
}
if ( result != nil )
{
ldap_msgfree( result );
result = nil;
}
}
catch( sInt32 err )
{
CShared::LogIt( 0x0F, "LDAP PlugIn: Crypt authentication error %l", err );
siResult = err;
}
if ( attrs != nil )
{
for ( int i = 0; attrs[i] != nil; ++i )
{
free( attrs[i] );
}
free( attrs );
attrs = nil;
}
if ( userName != nil )
{
delete( userName );
userName = nil;
}
if ( pwd != nil )
{
delete( pwd );
pwd = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
return( siResult );
}
sInt32 CLDAPPlugIn::DoClearTextAuth ( sLDAPContextData *inContext, tDataBuffer *inAuthData, bool authCheckOnly )
{
sInt32 siResult = eDSAuthFailed;
char *pData = nil;
char *userName = nil;
char *accountId = nil;
sInt32 nameLen = 0;
char *pwd = nil;
sInt32 pwdLen = 0;
int ldapBindReturn = LDAP_INVALID_CREDENTIALS;
bool clearCredentials = false;
sLDAPConfigData *pConfig = nil;
int bindMsgId = 0;
LDAPMessage *result = nil;
int openTO = 0;
try
{
if ( inContext == nil ) throw( (sInt32)eDSBadContextData );
if ( inAuthData == nil ) throw( (sInt32)eDSNullDataBuff );
pData = inAuthData->fBufferData;
if ( pData == nil ) throw( (sInt32)eDSNullDataBuff );
::memcpy( &nameLen, pData, sizeof( long ) );
if (nameLen > 0)
{
userName = (char *) calloc(1, nameLen + 1);
if ( userName == nil ) throw( (sInt32)eMemoryError );
pData += sizeof( long );
::memcpy( userName, pData, nameLen );
pData += nameLen;
}
::memcpy( &pwdLen, pData, sizeof( long ) );
if (pwdLen > 0)
{
pwd = (char *) calloc(1, pwdLen + 1);
if ( pwd == nil ) throw( (sInt32)eMemoryError );
pData += sizeof( long );
::memcpy( pwd, pData, pwdLen );
pData += pwdLen;
}
if ((nameLen == 0) && (pwdLen == 0) && (!authCheckOnly))
{
clearCredentials = true;
}
CShared::LogIt( 0x0F, "LDAP PlugIn: Attempting Auth Server Cleartext Authentication" );
if (userName)
{
accountId = GetDNForRecordName ( userName, inContext );
}
if (!accountId)
{
throw( (sInt32)eDSAuthFailed);
}
if ((pwd != NULL) && (pwd[0] != '\0') && (nameLen != 0))
{
bindMsgId = ldap_bind( inContext->fHost, accountId, pwd, LDAP_AUTH_SIMPLE );
if ( bindMsgId == -1 )
{
ldap_unbind( inContext->fHost );
inContext->fHost = NULL;
inContext->fHost = ldap_init( inContext->fName, inContext->fPort );
if ( inContext->fHost == nil ) throw( (sInt32)eDSCannotAccessSession );
gLDAPOpenMutex->Wait();
bindMsgId = ldap_bind( inContext->fHost, accountId, pwd, LDAP_AUTH_SIMPLE );
gLDAPOpenMutex->Signal();
if (bindMsgId == -1)
{
throw( (sInt32)eDSCannotAccessSession);
}
}
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
openTO = pConfig->fOpenCloseTimeout;
}
}
if (openTO == 0)
{
ldapBindReturn = ldap_result(inContext->fHost, bindMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = openTO;
tv.tv_usec = 0;
ldapBindReturn = ldap_result(inContext->fHost, bindMsgId, 0, &tv, &result);
}
if ( ldapBindReturn == -1 )
{
throw( (sInt32)eDSCannotAccessSession);
}
else if ( ldapBindReturn == 0 )
{
ldap_abandon(inContext->fHost, bindMsgId);
throw( (sInt32)eDSCannotAccessSession);
}
else
{
ldapBindReturn = ldap_result2error(inContext->fHost, result, 1);
}
bindMsgId = 0;
result = nil;
if (ldapBindReturn == LDAP_SUCCESS)
{
siResult = eDSNoErr;
if (!authCheckOnly)
{
if (inContext->authAccountName)
{
delete inContext->authAccountName;
inContext->authAccountName = nil;
}
if (inContext->authPassword)
{
delete inContext->authPassword;
inContext->authPassword = nil;
}
if (clearCredentials)
{
inContext->authCallActive = false;
}
else
{
inContext->authCallActive = true;
if (accountId)
{
inContext->authAccountName = new char(1+::strlen(accountId));
::strcpy(inContext->authAccountName, accountId);
}
if (pwd)
{
inContext->authPassword = new char(1+::strlen(pwd));
::strcpy(inContext->authPassword, pwd);
}
} }
}
else if (ldapBindReturn == LDAP_INVALID_CREDENTIALS)
{
throw( (sInt32)eDSAuthFailed);
}
else if (ldapBindReturn == LDAP_AUTH_UNKNOWN)
{
throw( (sInt32)eDSAuthFailed);
}
else
{
throw( (sInt32)eDSCannotAccessSession);
}
}
}
catch( sInt32 err )
{
CShared::LogIt( 0x0F, "LDAP PlugIn: Cleartext authentication error %l", err );
siResult = err;
}
if ( accountId != nil )
{
delete( accountId );
accountId = nil;
}
if ( userName != nil )
{
delete( userName );
userName = nil;
}
if ( pwd != nil )
{
delete( pwd );
pwd = nil;
}
return( siResult );
}
char* CLDAPPlugIn::GetDNForRecordName ( char* inRecName, sLDAPContextData *inContext )
{
char *ldapDN = nil;
char *pLDAPRecType = nil;
int ldapMsgId = 0;
char *queryFilter = nil;
LDAPMessage *result = nil;
int ldapReturnCode = 0;
int numRecTypes = 1;
bool bResultFound = false;
sLDAPConfigData *pConfig = nil;
int searchTO = 0;
sInt32 siResult = eDSNoErr;
try
{
if ( inRecName == nil ) throw( (sInt32)eDSNullRecName );
if ( inContext == nil ) throw( (sInt32)eDSBadContextData );
queryFilter = BuildLDAPQueryFilter((char *)kDSNAttrRecordName, inRecName, eDSExact, inContext->fConfigTableIndex, false);
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
siResult = RebindTryProc(inContext);
if ( siResult != eDSNoErr ) throw( siResult );
numRecTypes = 1;
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while ( (pLDAPRecType != nil) && (!bResultFound) )
{
if ( (ldapMsgId = ldap_search( inContext->fHost, pLDAPRecType, LDAP_SCOPE_SUBTREE, queryFilter, NULL, 0) ) == -1 )
{
bResultFound = false;
}
else
{
bResultFound = true;
if (searchTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = searchTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, ldapMsgId, 0, &tv, &result);
}
}
if (pLDAPRecType != nil)
{
delete (pLDAPRecType);
pLDAPRecType = nil;
}
numRecTypes++;
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes );
}
if ( (bResultFound) && ( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) )
{
ldapDN = ldap_get_dn(inContext->fHost, result);
}
if ( result != nil )
{
ldap_msgfree( result );
result = nil;
}
}
catch( sInt32 err )
{
ldapDN = nil;
}
if ( pLDAPRecType != nil )
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
return( ldapDN );
}
sInt32 CLDAPPlugIn::DoPlugInCustomCall ( sDoPlugInCustomCall *inData )
{
sInt32 siResult = eDSNoErr;
unsigned long aRequest = 0;
sLDAPContextData *pContext = nil;
sInt32 xmlDataLength = 0;
CFDataRef xmlData = nil;
unsigned long bufLen = 0;
AuthorizationRef authRef = 0;
AuthorizationItemSet *resultRightSet = NULL;
try
{
if ( inData == nil ) throw( (sInt32)eDSNullParameter );
if ( inData->fInRequestData == nil ) throw( (sInt32)eDSNullDataBuff );
if ( inData->fInRequestData->fBufferData == nil ) throw( (sInt32)eDSEmptyBuffer );
pContext = (sLDAPContextData *)gRefTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
if ( strcmp(pContext->fName,"LDAPv2 Configure") == 0 )
{
aRequest = inData->fInRequestCode;
bufLen = inData->fInRequestData->fBufferLength;
if ( bufLen < sizeof( AuthorizationExternalForm ) ) throw( (sInt32)eDSInvalidBuffFormat );
siResult = AuthorizationCreateFromExternalForm((AuthorizationExternalForm *)inData->fInRequestData->fBufferData,
&authRef);
if (siResult != errAuthorizationSuccess)
{
throw( (sInt32)eDSPermissionError );
}
AuthorizationItem rights[] = { {"system.services.directory.configure", 0, 0, 0} };
AuthorizationItemSet rightSet = { sizeof(rights)/ sizeof(*rights), rights };
siResult = AuthorizationCopyRights(authRef, &rightSet, NULL,
kAuthorizationFlagExtendRights, &resultRightSet);
if (resultRightSet != NULL)
{
AuthorizationFreeItemSet(resultRightSet);
resultRightSet = NULL;
}
if (siResult != errAuthorizationSuccess)
{
throw( (sInt32)eDSPermissionError );
}
switch( aRequest )
{
case 66:
if ( inData->fOutRequestResponse == nil ) throw( (sInt32)eDSNullDataBuff );
if ( inData->fOutRequestResponse->fBufferData == nil ) throw( (sInt32)eDSEmptyBuffer );
if ( inData->fOutRequestResponse->fBufferSize < sizeof( CFIndex ) ) throw( (sInt32)eDSInvalidBuffFormat );
if (pConfigFromXML)
{
xmlData = pConfigFromXML->GetXMLConfig();
if (xmlData != 0)
{
CFRetain(xmlData);
*(CFIndex*)(inData->fOutRequestResponse->fBufferData) = CFDataGetLength(xmlData);
inData->fOutRequestResponse->fBufferLength = sizeof( CFIndex );
CFRelease(xmlData);
xmlData = 0;
}
}
break;
case 77:
CFRange aRange;
if ( inData->fOutRequestResponse == nil ) throw( (sInt32)eDSNullDataBuff );
if ( inData->fOutRequestResponse->fBufferData == nil ) throw( (sInt32)eDSEmptyBuffer );
if (pConfigFromXML)
{
xmlData = pConfigFromXML->GetXMLConfig();
if (xmlData != 0)
{
CFRetain(xmlData);
aRange.location = 0;
aRange.length = CFDataGetLength(xmlData);
if ( inData->fOutRequestResponse->fBufferSize < (unsigned int)aRange.length) throw( (sInt32)eDSBufferTooSmall );
CFDataGetBytes( xmlData, aRange, (UInt8*)(inData->fOutRequestResponse->fBufferData) );
inData->fOutRequestResponse->fBufferLength = aRange.length;
CFRelease(xmlData);
xmlData = 0;
}
}
break;
case 88:
xmlDataLength = (sInt32) bufLen - sizeof( AuthorizationExternalForm );
if ( xmlDataLength <= 0) throw( (sInt32)eDSInvalidBuffFormat );
xmlData = CFDataCreate(NULL,(UInt8 *)(inData->fInRequestData->fBufferData + sizeof( AuthorizationExternalForm )),
xmlDataLength);
if (pConfigFromXML)
{
siResult = pConfigFromXML->SetXMLConfig(xmlData);
siResult = pConfigFromXML->WriteXMLConfig();
Initialize();
}
CFRelease(xmlData);
break;
case 99:
Initialize();
break;
default:
break;
}
}
}
catch( sInt32 err )
{
siResult = err;
}
if (authRef != 0)
{
AuthorizationFree(authRef, 0);
authRef = 0;
}
return( siResult );
}
void CLDAPPlugIn::ContextDeallocProc ( void* inContextData )
{
sLDAPContextData *pContext = (sLDAPContextData *) inContextData;
if ( pContext != nil )
{
CleanContextData( pContext );
free( pContext );
pContext = nil;
}
}
sInt32 CLDAPPlugIn:: RebindTryProc ( sLDAPContextData *inContext )
{
sInt32 siResult = eDSNoErr;
int ldapReturnCode = 0;
int bindMsgId = 0;
LDAPMessage *result = nil;
sLDAPConfigData *pConfig = nil;
char *ldapAcct = nil;
char *ldapPasswd = nil;
int openTO = 0;
try
{
if ( inContext->fHost == nil ) throw( (sInt32)eDSCannotAccessSession );
if (!(inContext->authCallActive))
{
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
if (pConfig->bSecureUse)
{
if (pConfig->fServerAccount != nil)
{
ldapAcct = new char[1+::strlen(pConfig->fServerAccount)];
::strcpy( ldapAcct, pConfig->fServerAccount );
}
if (pConfig->fServerPassword != nil)
{
ldapPasswd = new char[1+::strlen(pConfig->fServerPassword)];
::strcpy( ldapPasswd, pConfig->fServerPassword );
}
}
openTO = pConfig->fOpenCloseTimeout;
}
}
bindMsgId = ldap_bind( inContext->fHost, ldapAcct, ldapPasswd, LDAP_AUTH_SIMPLE );
if ( (bindMsgId == -1) && (inContext->msgId == 0) )
{
ldap_unbind( inContext->fHost );
inContext->fHost = NULL;
inContext->fHost = ldap_init( inContext->fName, inContext->fPort );
if ( inContext->fHost == nil ) throw( (sInt32)eDSCannotAccessSession );
gLDAPOpenMutex->Wait();
bindMsgId = ldap_bind( inContext->fHost, ldapAcct, ldapPasswd, LDAP_AUTH_SIMPLE );
gLDAPOpenMutex->Signal();
if (bindMsgId == -1)
{
throw( (sInt32)eDSCannotAccessSession);
}
}
else if ( bindMsgId == -1 )
{
throw( (sInt32)eDSCannotAccessSession);
}
if (openTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, bindMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = openTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, bindMsgId, 0, &tv, &result);
}
if ( ldapReturnCode == -1 )
{
ldap_unbind( inContext->fHost );
inContext->fHost = NULL;
inContext->fHost = ldap_init( inContext->fName, inContext->fPort );
if ( inContext->fHost == nil ) throw( (sInt32)eDSCannotAccessSession );
gLDAPOpenMutex->Wait();
bindMsgId = ldap_bind( inContext->fHost, ldapAcct, ldapPasswd, LDAP_AUTH_SIMPLE );
gLDAPOpenMutex->Signal();
if (bindMsgId == -1)
{
throw( (sInt32)eDSCannotAccessSession);
}
if (openTO == 0)
{
ldapReturnCode = ldap_result(inContext->fHost, bindMsgId, 0, NULL, &result);
}
else
{
struct timeval tv;
tv.tv_sec = openTO;
tv.tv_usec = 0;
ldapReturnCode = ldap_result(inContext->fHost, bindMsgId, 0, &tv, &result);
}
}
if ( ldapReturnCode == -1 )
{
throw( (sInt32)eDSCannotAccessSession);
}
else if ( ldapReturnCode == 0 )
{
ldap_abandon(inContext->fHost, bindMsgId);
throw( (sInt32)eDSCannotAccessSession);
}
else if ( ldap_result2error(inContext->fHost, result, 1) != LDAP_SUCCESS )
{
throw( (sInt32)eDSCannotAccessSession);
}
bindMsgId = 0;
ldapReturnCode = 0;
result = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if (ldapAcct != nil)
{
delete (ldapAcct);
ldapAcct = nil;
}
if (ldapPasswd != nil)
{
delete (ldapPasswd);
ldapPasswd = nil;
}
return (siResult);
}