#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 <SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h>
#include <DirectoryService/DirServices.h>
#include <DirectoryService/DirServicesUtils.h>
#include <DirectoryService/DirServicesConst.h>
#include "CLDAPv3PlugIn.h"
#include <list>
using namespace std;
typedef list<string> listOfStrings;
typedef listOfStrings::const_iterator listOfStringsCI;
#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>
#include <DirectoryServiceCore/PrivateTypes.h>
#define LDAPURLOPT95SEPCHAR " "
#define LDAPCOMEXPSPECIALCHARS "()|&"
typedef struct AuthAuthorityHandler {
char* fTag;
AuthAuthorityHandlerProc fHandler;
} AuthAuthorityHandler;
#define kAuthAuthorityHandlerProcs 2
static AuthAuthorityHandler sAuthAuthorityHandlerProcs[ kAuthAuthorityHandlerProcs ] =
{
{ "basic", (AuthAuthorityHandlerProc)CLDAPv3PlugIn::DoBasicAuth },
{ "ApplePasswordServer", (AuthAuthorityHandlerProc)CLDAPv3PlugIn::DoPasswordServerAuth }
};
CContinue *gLDAPContinueTable = nil;
CPlugInRef *gLDAPContextTable = nil;
CPlugInRef *gConfigTable = nil; uInt32 gConfigTableLen = 0;
static DSEventSemaphore *gKickSearchRequests = nil;
sInt32 DSSearchLDAP ( CLDAPNode &inLDAPSessionMgr,
sLDAPContextData *inContext,
char *inNativeRecType,
int scope,
char *queryFilter,
char **attrs,
int &ldapMsgId,
int &ldapReturnCode);
sInt32 DSSearchLDAP ( CLDAPNode &inLDAPSessionMgr,
sLDAPContextData *inContext,
char *inNativeRecType,
int scope,
char *queryFilter,
char **attrs,
int &ldapMsgId,
int &ldapReturnCode)
{
sInt32 siResult = eDSNoErr;
LDAPControl **serverctrls = nil;
LDAPControl **clientctrls = nil;
LDAP *aHost = nil;
aHost = inLDAPSessionMgr.LockSession(inContext);
if (aHost != nil)
{
ldapReturnCode = ldap_search_ext( aHost,
inNativeRecType,
scope,
queryFilter,
attrs,
0,
serverctrls,
clientctrls,
0, 0,
&ldapMsgId );
}
else
{
ldapReturnCode = LDAP_LOCAL_ERROR;
}
inLDAPSessionMgr.UnLockSession(inContext);
if (serverctrls) ldap_controls_free( serverctrls );
if (clientctrls) ldap_controls_free( clientctrls );
switch(ldapReturnCode)
{
case LDAP_SUCCESS:
break;
case LDAP_UNAVAILABLE:
case LDAP_SERVER_DOWN:
case LDAP_BUSY:
case LDAP_LOCAL_ERROR:
siResult = eDSCannotAccessSession;
break;
default:
siResult = eDSRecordNotFound;
break;
}
return(siResult);
}
void DSGetSearchLDAPResult ( CLDAPNode &inLDAPSessionMgr,
sLDAPContextData *inContext,
int inSearchTO,
LDAPMessage *&inResult,
int all,
int &inLDAPMsgId,
int &inLDAPReturnCode,
bool bThrowOnNoEntry);
void DSGetSearchLDAPResult ( CLDAPNode &inLDAPSessionMgr,
sLDAPContextData *inContext,
int inSearchTO,
LDAPMessage *&inResult,
int all,
int &inLDAPMsgId,
int &inLDAPReturnCode,
bool bThrowOnNoEntry)
{
LDAP *aHost = nil;
aHost = inLDAPSessionMgr.LockSession(inContext);
if (inSearchTO == 0)
{
inLDAPReturnCode = ldap_result(aHost, inLDAPMsgId, all, NULL, &inResult);
}
else
{
struct timeval tv;
tv.tv_sec = inSearchTO;
tv.tv_usec = 0;
inLDAPReturnCode = ldap_result(aHost, inLDAPMsgId, all, &tv, &inResult);
}
inLDAPSessionMgr.UnLockSession(inContext);
switch(inLDAPReturnCode)
{
case LDAP_RES_SEARCH_ENTRY:
break;
case LDAP_RES_SEARCH_RESULT:
{
int ldapReturnCode2 = 0;
int err = 0;
char *matcheddn = nil;
char *text = nil;
char **refs = nil;
LDAPControl **ctrls = nil;
aHost = inLDAPSessionMgr.LockSession(inContext);
ldapReturnCode2 = ldap_parse_result(aHost, inResult, &err, &matcheddn, &text, &refs, &ctrls, 0);
inLDAPSessionMgr.UnLockSession(inContext);
if ( (ldapReturnCode2 != LDAP_SUCCESS) && (ldapReturnCode2 != LDAP_MORE_RESULTS_TO_RETURN) )
{
aHost = inLDAPSessionMgr.LockSession(inContext);
ldap_abandon(aHost, inLDAPMsgId);
inLDAPSessionMgr.UnLockSession(inContext);
}
else
{
if (ldapReturnCode2 == LDAP_SUCCESS) inLDAPReturnCode = LDAP_SUCCESS;
if (text) ber_memfree( text );
if (matcheddn) ber_memfree( matcheddn );
if (refs) ber_memvfree( (void **) refs );
if (ctrls) ldap_controls_free( ctrls );
}
if (bThrowOnNoEntry) throw( (sInt32)eDSRecordNotFound );
}
break;
case LDAP_TIMEOUT:
throw( (sInt32)eDSServerTimeout );
case LDAP_SUCCESS:
case -1:
default:
if (bThrowOnNoEntry)
{
throw( (sInt32)eDSRecordNotFound );
}
else
{
throw( (sInt32)eDSNoErr );
}
} }
void DSGetExtendedLDAPResult ( LDAP *inHost,
int inSearchTO,
int &inLDAPMsgId,
int &inLDAPReturnCode);
void DSGetExtendedLDAPResult ( LDAP *inHost,
int inSearchTO,
int &inLDAPMsgId,
int &inLDAPReturnCode)
{
LDAPMessage *res = NULL;
if (inSearchTO == 0)
{
inLDAPReturnCode = ldap_result(inHost, inLDAPMsgId, LDAP_MSG_ALL, NULL, &res);
}
else
{
struct timeval tv;
tv.tv_sec = inSearchTO;
tv.tv_usec = 0;
inLDAPReturnCode = ldap_result(inHost, inLDAPMsgId, LDAP_MSG_ALL, &tv, &res);
}
switch(inLDAPReturnCode)
{
case LDAP_RES_SEARCH_ENTRY:
break;
case LDAP_RES_EXTENDED:
case LDAP_RES_SEARCH_RESULT:
{
int ldapReturnCode2 = 0;
int err = 0;
char *matcheddn = nil;
char *text = nil;
char **refs = nil;
LDAPControl **ctrls = nil;
ldapReturnCode2 = ldap_parse_result(inHost, res, &err, &matcheddn, &text, &refs, &ctrls, 0);
if ( (ldapReturnCode2 != LDAP_SUCCESS) && (ldapReturnCode2 != LDAP_MORE_RESULTS_TO_RETURN) )
{
ldap_abandon(inHost, inLDAPMsgId);
inLDAPReturnCode = ldapReturnCode2;
}
else
{
inLDAPReturnCode = err;
if (text && *text) ber_memfree( text );
if (matcheddn && *matcheddn) ber_memfree( matcheddn );
if (refs) ber_memvfree( (void **) refs );
if (ctrls) ldap_controls_free( ctrls );
}
}
break;
case LDAP_TIMEOUT:
case LDAP_SUCCESS:
case -1:
default:
break;
} }
static int standard_password_create( LDAP *ld, char *dn, char *newPwd );
static int standard_password_create( LDAP *ld, char *dn, char *newPwd )
{
LDAPMod modRemove = {};
modRemove.mod_op = LDAP_MOD_DELETE;
modRemove.mod_type = "userPassword";
modRemove.mod_values = NULL;
char *pwdCreate[2] = {};
pwdCreate[0] = newPwd;
pwdCreate[1] = NULL;
LDAPMod modAdd = {};
modAdd.mod_op = LDAP_MOD_ADD;
modAdd.mod_type = "userPassword";
modAdd.mod_values = pwdCreate;
LDAPMod *mods[3] = {};
mods[0] = &modRemove;
mods[1] = &modAdd;
mods[2] = NULL;
return ldap_modify_s( ld, dn, mods );
}
static int exop_password_create( LDAP *ld, char *dn, char *newPwd );
static int exop_password_create( LDAP *ld, char *dn, char *newPwd )
{
BerElement *ber = ber_alloc_t( LBER_USE_DER );
if( ber == NULL ) throw( (sInt32) eMemoryError );
ber_printf( ber, "{" );
ber_printf( ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, dn );
ber_printf( ber, "ts", LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, newPwd );
ber_printf( ber, "N}" );
struct berval *bv = NULL;
int rc = ber_flatten( ber, &bv );
if( rc < 0 ) throw( (sInt32) eMemoryError );
ber_free( ber, 1 );
int id;
rc = ldap_extended_operation( ld, LDAP_EXOP_MODIFY_PASSWD, bv, NULL, NULL, &id );
ber_bvfree( bv );
if ( rc == LDAP_SUCCESS ) {
DSGetExtendedLDAPResult( ld, 0, id, rc);
}
return rc;
}
static const uInt32 kBuffPad = 16;
extern "C" {
CFUUIDRef ModuleFactoryUUID = CFUUIDGetConstantUUIDWithBytes ( NULL, \
0x79, 0xDC, 0xEC, 0x6E, 0xE4, 0x51, 0x11, 0xD5, \
0x95, 0xD1, 0x00, 0x30, 0x65, 0xAB, 0x56, 0x3E );
}
static CDSServerModule* _Creator ( void )
{
return( new CLDAPv3PlugIn );
}
CDSServerModule::tCreator CDSServerModule::sCreator = _Creator;
CLDAPv3PlugIn::CLDAPv3PlugIn ( void )
{
fState = kUnknownState;
fDefaultLDAPNodeCount = 0;
pConfigFromXML = nil;
bCheckForDHCPLDAPServers= true;
fDHCPLDAPServersString = NULL;
bDoNotInitTwiceAtStartUp= true;
for (uInt32 idx = 0; idx < MaxDefaultLDAPNodeCount; idx++ )
{
pDefaultLDAPNodes[idx] = nil;
}
if ( gLDAPContinueTable == nil )
{
gLDAPContinueTable = new CContinue( CLDAPv3PlugIn::ContinueDeallocProc );
}
if ( gConfigTable == nil )
{
gConfigTable = new CPlugInRef( nil ); }
if ( gLDAPContextTable == nil )
{
gLDAPContextTable = new CPlugInRef( CLDAPv3PlugIn::ContextDeallocProc );
}
if ( gKickSearchRequests == nil )
{
gKickSearchRequests = new DSEventSemaphore();
}
}
CLDAPv3PlugIn::~CLDAPv3PlugIn ( void )
{
if ( pConfigFromXML != nil)
{
delete ( pConfigFromXML );
pConfigFromXML = nil;
gConfigTable = nil;
gConfigTableLen = 0;
pStdAttributeMapTuple = nil;
pStdRecordMapTuple = nil;
}
if ( gLDAPContinueTable != nil)
{
delete ( gLDAPContinueTable );
gLDAPContinueTable = nil;
}
}
sInt32 CLDAPv3PlugIn::Validate ( const char *inVersionStr, const uInt32 inSignature )
{
fSignature = inSignature;
return( noErr );
}
sInt32 CLDAPv3PlugIn::Initialize ( void )
{
int countNodes = 0;
sInt32 siResult = eDSNoErr;
tDataList *pldapName = nil;
sLDAPConfigData *pConfig = nil;
uInt32 iTableIndex = 0;
bool bRetainDHCP = true;
char *server = nil;
char *searchBase = nil;
int portNumber = 389;
bool bIsSSL = false;
try
{
if ( pConfigFromXML == nil )
{
pConfigFromXML = new CLDAPv3Configs();
if ( pConfigFromXML == nil ) throw( (sInt32)eDSOpenNodeFailed ); }
siResult = pConfigFromXML->Init( gConfigTable, gConfigTableLen, &pStdAttributeMapTuple, &pStdRecordMapTuple );
if ( siResult != eDSNoErr ) throw( siResult );
if (bCheckForDHCPLDAPServers) {
bCheckForDHCPLDAPServers = false; CFDictionaryRef ourDHCPInfo = NULL;
CFStringRef ourDHCPServers = NULL;
CFDataRef ourDHCPServersData = NULL;
UInt8 *byteData = NULL;
ourDHCPInfo = SCDynamicStoreCopyDHCPInfo(NULL, NULL);
if (ourDHCPInfo != NULL)
{
ourDHCPServersData = (CFDataRef) DHCPInfoGetOptionData(ourDHCPInfo, 95);
if (ourDHCPServersData != NULL)
{
byteData = (UInt8 *) calloc(1, CFDataGetLength(ourDHCPServersData));
if (byteData != NULL)
{
CFDataGetBytes(ourDHCPServersData, CFRangeMake( 0,
CFDataGetLength(ourDHCPServersData)),
byteData);
if (byteData[0] != '\0')
{
ourDHCPServers = CFStringCreateWithBytes( kCFAllocatorDefault,
byteData,
CFDataGetLength(ourDHCPServersData),
kCFStringEncodingUTF8,
false);
}
free(byteData);
} }
if (ourDHCPServers != NULL)
{
if ( CFGetTypeID( ourDHCPServers ) == CFStringGetTypeID() )
{
if (( fDHCPLDAPServersString == NULL) || (CFStringCompare(fDHCPLDAPServersString, ourDHCPServers, 0) != kCFCompareEqualTo))
{
bRetainDHCP = false;
if (fDHCPLDAPServersString != NULL)
{
CFRelease(fDHCPLDAPServersString);
}
fDHCPLDAPServersString = ourDHCPServers;
if (fDefaultLDAPNodeCount > 0)
{
for (uInt32 idx = 0; idx < fDefaultLDAPNodeCount; idx++ )
{
free(pDefaultLDAPNodes[idx]);
pDefaultLDAPNodes[idx] = nil;
}
fDefaultLDAPNodeCount = 0;
}
int serverIndex = 1;
while( ParseNextDHCPLDAPServerString(&server, &searchBase, &portNumber, &bIsSSL, serverIndex) )
{
pConfigFromXML->ConfigDHCPObtainedLDAPServer(server, searchBase, portNumber, bIsSSL, gConfigTableLen);
if (server != nil)
{
free(server);
server = nil;
}
if (searchBase != nil)
{
free(searchBase);
searchBase = nil;
}
portNumber = 389;
bIsSSL = false;
serverIndex++;
}
} } } else
{
}
CFRelease(ourDHCPInfo);
} } if (bRetainDHCP)
{
for (iTableIndex=1; iTableIndex<gConfigTableLen; iTableIndex++)
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( iTableIndex );
if (pConfig != nil)
{
if (pConfig->bUseAsDefaultLDAP)
{
pConfig->bUpdated = true; }
}
}
}
for (iTableIndex=1; iTableIndex<gConfigTableLen; iTableIndex++)
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( iTableIndex );
if (pConfig != nil)
{
if (pConfig->fServerName != nil)
{
if (pConfig->bUpdated)
{
if (pConfig->bUseAsDefaultLDAP)
{
char *theDHCPNodeName = (char *) calloc(1, 1+8+strlen(pConfig->fServerName));
strcpy(theDHCPNodeName, "/LDAPv3/");
strcat(theDHCPNodeName, pConfig->fServerName);
bool bDHCPLDAPNodeNotDuplicate = true;
for (uInt32 idx = 0; idx < fDefaultLDAPNodeCount; idx++ )
{
if (pDefaultLDAPNodes[idx] != nil)
{
if (strcmp(pDefaultLDAPNodes[idx], theDHCPNodeName) == 0)
{
bDHCPLDAPNodeNotDuplicate = false;
break;
}
}
}
if (bDHCPLDAPNodeNotDuplicate)
{
pDefaultLDAPNodes[fDefaultLDAPNodeCount] = theDHCPNodeName;
fDefaultLDAPNodeCount++;
}
else
{
free(theDHCPNodeName);
theDHCPNodeName = nil;
}
}
countNodes++;
pConfig->bAvail = true;
pldapName = dsBuildListFromStringsPriv((char *)"LDAPv3", pConfig->fServerName, nil);
if (pldapName != nil)
{
DSRegisterNode( fSignature, pldapName, kDirNodeType );
dsDataListDeallocatePriv( pldapName);
free(pldapName);
pldapName = nil;
}
} else
{
pldapName = dsBuildListFromStringsPriv((char *)"LDAPv3", 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 );
}
bool CLDAPv3PlugIn::ParseNextDHCPLDAPServerString ( char **inServer, char **inSearchBase, int *inPortNumber, bool *inIsSSL, int inServerIndex )
{
bool foundNext = false;
char *tmpBuff = nil;
char *aString = nil;
uInt32 callocLength = 0;
char *aToken = nil;
int aIndex = 1;
uInt32 strLength = 0;
char *ptr = nil;
if (fDHCPLDAPServersString == NULL)
{
return(foundNext);
}
callocLength = (uInt32) CFStringGetMaximumSizeForEncoding(CFStringGetLength(fDHCPLDAPServersString), kCFStringEncodingUTF8) + 1;
tmpBuff = (char *) calloc(1, callocLength);
CFStringGetCString( fDHCPLDAPServersString, tmpBuff, callocLength, kCFStringEncodingUTF8 );
aString = tmpBuff;
aToken = strsep(&aString,LDAPURLOPT95SEPCHAR);
if (inServerIndex > 1)
{
aIndex = inServerIndex;
while (aIndex != 1)
{
aToken = strsep(&aString, LDAPURLOPT95SEPCHAR);
aIndex--;
}
}
if (aToken != nil)
{
*inServer = nil;
*inSearchBase = nil;
if ( strncmp(aToken,"ldap://",7) == 0 )
{
*inPortNumber = 389;
*inIsSSL = false;
aToken = aToken + 7;
}
else if ( strncmp(aToken,"ldaps://",8) == 0 )
{
*inPortNumber = 636;
*inIsSSL = true;
aToken = aToken + 8;
}
else
{
syslog(LOG_INFO,"DSLDAPv3PlugIn: DHCP option 95 error since obtained [%s] LDAP server prefix is not of the correct format.", aToken);
if ( tmpBuff != nil )
{
free(tmpBuff);
tmpBuff = nil;
}
return(foundNext);
}
ptr = aToken;
strLength = 0;
while ( (*ptr != '\0') && (*ptr != ':') && (*ptr != '/') )
{
strLength++;
ptr++;
}
if (strLength != 0)
{
*inServer = (char *) calloc(1, strLength+1);
strncpy(*inServer, aToken, strLength);
aToken = aToken + strLength;
foundNext = true;
}
else
{
syslog(LOG_INFO,"DSLDAPv3PlugIn: DHCP option 95 error since can't extract LDAP server name from URL.");
if ( tmpBuff != nil )
{
free(tmpBuff);
tmpBuff = nil;
}
return(foundNext);
}
if (*ptr == ':')
{
ptr++;
aToken++;
strLength = 0;
while ( (*ptr != '\0') && (*ptr != '/') )
{
strLength++;
ptr++;
}
if (strLength != 0)
{
char *portStr = nil;
portStr = (char *) calloc(1, strLength+1);
strncpy(portStr, aToken, strLength);
*inPortNumber = atoi(portStr);
free(portStr);
portStr = nil;
aToken = aToken + strLength;
}
}
if (*ptr == '/')
{
ptr++;
aToken++;
strLength = 0;
while ( (*ptr != '\0') && (*ptr != '?') )
{
strLength++;
ptr++;
}
if (strLength != 0)
{
*inSearchBase = (char *) calloc(1, strLength+1);
strncpy(*inSearchBase, aToken, strLength);
ptr = *inSearchBase;
char *BasePtr = ptr;
while (*ptr != '\0')
{
if (*ptr == '%')
{
ptr++;
if (*ptr == '2')
{
ptr++;
if (*ptr == '0')
{
*ptr = ' ';
}
}
}
*BasePtr = *ptr;
ptr++;
BasePtr++;
}
*BasePtr = *ptr; }
}
}
if ( tmpBuff != nil )
{
free(tmpBuff);
tmpBuff = nil;
}
return(foundNext);
}
sInt32 CLDAPv3PlugIn::SetPluginState ( const uInt32 inState )
{
tDataList *pldapName = nil;
sLDAPConfigData *pConfig = nil;
uInt32 iTableIndex = 0;
if (kActive & inState) {
if ( (fState & kActive) && (bDoNotInitTwiceAtStartUp) ) {
bDoNotInitTwiceAtStartUp = false;
}
else
{
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 *)"LDAPv3", 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 CLDAPv3PlugIn::WakeUpRequests ( void )
{
gKickSearchRequests->Signal();
}
void CLDAPv3PlugIn::WaitForInit ( void )
{
volatile uInt32 uiAttempts = 0;
if (!(fState & kActive))
{
while ( !(fState & kInitalized) &&
!(fState & kFailedToInit) )
{
if ( uiAttempts++ >= 240 )
{
return;
}
gKickSearchRequests->Wait( (uInt32)(.5 * kMilliSecsPerSec) );
gKickSearchRequests->Reset();
}
}}
sInt32 CLDAPv3PlugIn::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,"/LDAPv3",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 )
{
bCheckForDHCPLDAPServers = true; siResult = Initialize();
}
else
{
siResult = HandleRequest( inData );
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::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 kGetRecordAttributeValueByIndex:
siResult = GetRecAttrValueByIndex( (sGetRecordAttributeValueByIndex *)inData );
break;
case kGetRecordAttributeValueByID:
siResult = GetRecordAttributeValueByID( (sGetRecordAttributeValueByID *)inData );
break;
case kFlushRecord:
siResult = FlushRecord( (sFlushRecord *)inData );
break;
case kCloseAttributeList:
siResult = CloseAttributeList( (sCloseAttributeList *)inData );
break;
case kCloseAttributeValueList:
siResult = CloseAttributeValueList( (sCloseAttributeValueList *)inData );
break;
case kCloseRecord:
siResult = CloseRecord( (sCloseRecord *)inData );
break;
case kReleaseContinueData:
siResult = ReleaseContinueData( (sReleaseContinueData *)inData );
break;
case kSetRecordName:
siResult = SetRecordName( (sSetRecordName *)inData );
break;
case kSetRecordType:
siResult = eNotYetImplemented; break;
case kDeleteRecord:
siResult = DeleteRecord( (sDeleteRecord *)inData );
break;
case kCreateRecord:
case kCreateRecordAndOpen:
siResult = CreateRecord( (sCreateRecord *)inData );
break;
case kAddAttribute:
siResult = AddAttribute( (sAddAttribute *)inData );
break;
case kRemoveAttribute:
siResult = RemoveAttribute( (sRemoveAttribute *)inData );
break;
case kAddAttributeValue:
siResult = AddAttributeValue( (sAddAttributeValue *)inData );
break;
case kRemoveAttributeValue:
siResult = RemoveAttributeValue( (sRemoveAttributeValue *)inData );
break;
case kSetAttributeValue:
siResult = SetAttributeValue( (sSetAttributeValue *)inData );
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 CLDAPv3PlugIn::OpenDirNode ( sOpenDirNode *inData )
{
char *ldapName = nil;
char *pathStr = nil;
char *subStr = nil;
sLDAPContextData *pContext = nil;
sInt32 siResult = eDSNoErr;
tDataListPtr pNodeList = nil;
pNodeList = inData->fInDirNodeName;
PrintNodeName(pNodeList);
try
{
if ( inData != nil )
{
pathStr = dsGetPathFromListPriv( pNodeList, (char *)"/" );
if ( pathStr == nil ) throw( (sInt32)eDSNullNodeName );
if (::strcmp(pathStr,"/LDAPv3") == 0)
{
pContext = MakeContextData();
pContext->fHost = nil;
pContext->fName = new char[1+::strlen("LDAPv3 Configure")];
::strcpy(pContext->fName,"LDAPv3 Configure");
pContext->fConfigTableIndex = 0;
gLDAPContextTable->AddItem( inData->fOutNodeRef, pContext );
}
else if ( (strlen(pathStr) > 8) && (::strncmp(pathStr,"/LDAPv3/",8) == 0) )
{
subStr = pathStr + 8;
ldapName = (char *) calloc( 1, strlen(subStr) );
if ( ldapName == nil ) throw( (sInt32)eDSNullNodeName );
::strcpy(ldapName,subStr);
pContext = MakeContextData();
pContext->fName = ldapName;
siResult = fLDAPSessionMgr.SafeOpen( (char *)ldapName, &(pContext->fHost), &(pContext->fConfigTableIndex) );
if ( siResult != eDSNoErr) throw( (sInt32)eDSOpenNodeFailed );
gLDAPContextTable->AddItem( inData->fOutNodeRef, pContext );
} else
{
siResult = eDSOpenNodeFailed;
}
} } catch ( sInt32 err )
{
siResult = err;
if (pContext != nil)
{
gLDAPContextTable->RemoveItem( inData->fOutNodeRef );
}
}
if (pathStr != nil)
{
delete( pathStr );
pathStr = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::CloseDirNode ( sCloseDirNode *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
try
{
pContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
if ( pContext->authCallActive )
{
siResult = fLDAPSessionMgr.SafeClose(pContext->fName, pContext->fHost);
}
else
{
siResult = fLDAPSessionMgr.SafeClose(pContext->fName, nil);
}
gLDAPContextTable->RemoveItem( inData->fInNodeRef );
gLDAPContinueTable->RemoveItems( inData->fInNodeRef );
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sLDAPContextData* CLDAPv3PlugIn::MakeContextData ( void )
{
sLDAPContextData *pOut = nil;
sInt32 siResult = eDSNoErr;
pOut = (sLDAPContextData *) calloc(1, sizeof(sLDAPContextData));
if ( pOut != nil )
{
siResult = CleanContextData(pOut);
}
return( pOut );
}
sInt32 CLDAPv3PlugIn::CleanContextData ( sLDAPContextData *inContext )
{
sInt32 siResult = eDSNoErr;
if ( inContext == nil )
{
siResult = eDSBadContextData;
}
else
{
inContext->fHost = nil;
if (inContext->fName != nil)
{
free( inContext->fName );
}
inContext->fName = nil;
inContext->fPort = 389;
inContext->fConfigTableIndex= 0;
inContext->fType = 0; inContext->authCallActive = false;
inContext->offset = 0;
inContext->index = 1;
if (inContext->fOpenRecordType != nil)
{
free( inContext->fOpenRecordType );
inContext->fOpenRecordType = nil;
}
if (inContext->fOpenRecordName != nil)
{
free( inContext->fOpenRecordName );
inContext->fOpenRecordName = nil;
}
if (inContext->fOpenRecordDN != nil)
{
free( inContext->fOpenRecordDN );
inContext->fOpenRecordDN = nil;
}
if (inContext->fUserName != nil)
{
free( inContext->fUserName );
inContext->fUserName = nil;
}
if (inContext->fAuthCredential != nil)
{
free( inContext->fAuthCredential );
inContext->fAuthCredential = nil;
}
if (inContext->fAuthType != nil)
{
free( inContext->fAuthType );
inContext->fAuthType = nil;
}
if ( inContext->fPWSNodeRef != 0 )
dsCloseDirNode(inContext->fPWSNodeRef);
if ( inContext->fPWSRef != 0 )
dsCloseDirService(inContext->fPWSRef);
}
return( siResult );
}
void CLDAPv3PlugIn::PrintNodeName ( tDataListPtr inNodeList )
{
char *pPath = nil;
pPath = dsGetPathFromListPriv( inNodeList, (char *)"/" );
if ( pPath != nil )
{
CShared::LogIt( 0x0F, (char *)"CLDAPv3PlugIn::PrintNodeName" );
CShared::LogIt( 0x0F, pPath );
delete( pPath );
pPath = nil;
}
}
sInt32 CLDAPv3PlugIn::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;
sLDAPContinueData *pLDAPContinue = nil;
CBuff *outBuff = nil;
int numRecTypes = 1;
bool bBuffFull = false;
bool separateRecTypes = false;
uInt32 countDownRecTypes = 0;
bool bOCANDGroup = false;
CFArrayRef OCSearchList = nil;
ber_int_t scope = LDAP_SCOPE_SUBTREE;
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 *)gLDAPContextTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
if ( inData->fIOContinueData == nil )
{
pLDAPContinue = (sLDAPContinueData *)::calloc( 1, sizeof( sLDAPContinueData ) );
gLDAPContinueTable->AddItem( pLDAPContinue, inData->fInNodeRef );
pLDAPContinue->fRecNameIndex = 1;
pLDAPContinue->fRecTypeIndex = 1;
pLDAPContinue->fTotalRecCount = 0;
pLDAPContinue->fLimitRecSearch = 0;
if (inData->fOutRecEntryCount >= 0)
{
pLDAPContinue->fLimitRecSearch = inData->fOutRecEntryCount;
}
}
else
{
pLDAPContinue = (sLDAPContinueData *)inData->fIOContinueData;
if ( gLDAPContinueTable->VerifyItem( pLDAPContinue ) == false )
{
throw( (sInt32)eDSInvalidContinueData );
}
}
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() - pLDAPContinue->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( pLDAPContinue->fRecTypeIndex, &pRecType ) == eDSNoErr ) && (!bBuffFull)) && (!separateRecTypes))
{
numRecTypes = 1;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( pRecType, pContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, pConfigFromXML );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while (( pLDAPRecType != nil ) && (!bBuffFull))
{
while (( (cpRecNameList->GetAttribute( pLDAPContinue->fRecNameIndex, &pRecName ) == eDSNoErr) && ( siResult == eDSNoErr) ) && (!bBuffFull))
{
bBuffFull = false;
if ( ::strcmp( pRecName, kDSRecordsAll ) == 0 )
{
siResult = GetAllRecords( pRecType, pLDAPRecType, cpAttrTypeList, pContext, pLDAPContinue, bAttribOnly, outBuff, uiCount, bOCANDGroup, OCSearchList, scope );
}
else
{
siResult = GetTheseRecords( pRecName, pRecType, pLDAPRecType, pattMatch, cpAttrTypeList, pContext, pLDAPContinue, bAttribOnly, outBuff, uiCount, bOCANDGroup, OCSearchList, scope );
}
if ( siResult == CBuff::kBuffFull )
{
bBuffFull = true;
inData->fIOContinueData = pLDAPContinue;
if ( ( uiCount == 0 ) && ( uiTotal == 0 ) )
{
throw( (sInt32)eDSBufferTooSmall );
}
uiTotal += uiCount;
inData->fOutRecEntryCount = uiTotal;
outBuff->SetLengthToSize();
siResult = eDSNoErr;
}
else if ( siResult == eDSNoErr )
{
uiTotal += uiCount;
pLDAPContinue->fRecNameIndex++;
}
}
if (pLDAPRecType != nil)
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if (!bBuffFull)
{
numRecTypes++;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( pRecType, pContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, pConfigFromXML );
}
}
if (!bBuffFull)
{
pRecType = nil;
pLDAPContinue->fRecTypeIndex++;
pLDAPContinue->fRecNameIndex = 1;
pLDAPContinue->msgId = 0;
separateRecTypes = true;
inData->fIOContinueData = pLDAPContinue;
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 (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
if ( (inData->fIOContinueData == nil) && (pLDAPContinue != nil) )
{
gLDAPContinueTable->RemoveItem( pLDAPContinue );
pLDAPContinue = nil;
}
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* CLDAPv3PlugIn::MapRecToLDAPType ( char *inRecType, uInt32 inConfigTableIndex, int inIndex, bool *outOCGroup, CFArrayRef *outOCListCFArray, ber_int_t *outScope, CLDAPv3Configs *inConfigFromXML )
{
char *outResult = nil;
uInt32 uiStrLen = 0;
uInt32 uiNativeLen = ::strlen( kDSNativeRecordTypePrefix );
uInt32 uiStdLen = ::strlen( kDSStdRecordTypePrefix );
sLDAPConfigData *pConfig = nil;
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)
{
if (inConfigFromXML != nil)
{
if (pConfig->fRecordTypeMapCFArray == 0)
{
}
outResult = inConfigFromXML->ExtractRecMap(inRecType, pConfig->fRecordTypeMapCFArray, inIndex, outOCGroup, outOCListCFArray, outScope );
}
}
}
} else
{
if ( inIndex == 1 )
{
outResult = new char[ 1 + ::strlen( inRecType ) ];
::strcpy( outResult, inRecType );
}
}
}
return( outResult );
}
sInt32 CLDAPv3PlugIn::GetAllRecords ( char *inRecType,
char *inNativeRecType,
CAttributeList *inAttrTypeList,
sLDAPContextData *inContext,
sLDAPContinueData *inContinue,
bool inAttrOnly,
CBuff *inBuff,
uInt32 &outRecCount,
bool inbOCANDGroup,
CFArrayRef inOCSearchList,
ber_int_t inScope )
{
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;
char *queryFilter = nil;
char **attrs = nil;
queryFilter = BuildLDAPQueryFilter( nil,
nil,
eDSAnyMatch,
inContext->fConfigTableIndex,
false,
inRecType,
inNativeRecType,
inbOCANDGroup,
inOCSearchList,
pConfigFromXML );
outRecCount = 0;
try
{
if (inContext == nil ) throw( (sInt32)eDSInvalidContext);
if (inContinue == nil ) throw( (sInt32)eDSInvalidContinueData);
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;
}
}
if (inContinue->msgId == 0)
{
attrs = MapAttrListToLDAPTypeArray( inRecType, inAttrTypeList, inContext->fConfigTableIndex );
int numRetries = 2;
while (true)
{
sInt32 searchResult = eDSNoErr;
searchResult = DSSearchLDAP( fLDAPSessionMgr,
inContext,
inNativeRecType,
inScope,
queryFilter,
attrs,
ldapMsgId,
ldapReturnCode);
if (searchResult == eDSRecordNotFound) throw( (sInt32)eDSNoErr );
if (searchResult == eDSCannotAccessSession)
{
if (numRetries == 0)
{
throw( (sInt32)eDSCannotAccessSession );
}
else
{
RebindLDAPSession(inContext, fLDAPSessionMgr);
numRetries--;
}
}
else
{
break;
}
}
inContinue->msgId = ldapMsgId;
} else
{
ldapMsgId = inContinue->msgId;
}
if ( (inContinue->fTotalRecCount < inContinue->fLimitRecSearch) || (inContinue->fLimitRecSearch == 0) )
{
if (inContinue->pResult != nil)
{
result = inContinue->pResult;
ldapReturnCode = LDAP_RES_SEARCH_ENTRY;
}
else
{
DSGetSearchLDAPResult ( fLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
false);
} }
while ( ( (ldapReturnCode == LDAP_RES_SEARCH_ENTRY) || (ldapReturnCode == LDAP_RES_SEARCH_RESULT) )
&& !(bufferFull)
&& ( (inContinue->fTotalRecCount < inContinue->fLimitRecSearch) ||
(inContinue->fLimitRecSearch == 0) ) )
{
if (ldapReturnCode == LDAP_RES_SEARCH_ENTRY)
{
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( inRecType, 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( inRecType, 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;
inContinue->pResult = result;
}
else if ( siResult == eDSNoErr )
{
ldap_msgfree( result );
if (ldapReturnCode == LDAP_RES_SEARCH_ENTRY)
{
outRecCount++; inContinue->fTotalRecCount++;
}
inContinue->pResult = nil;
DSGetSearchLDAPResult ( fLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
false);
}
else
{
inContinue->pResult = nil;
throw( (sInt32)eDSInvalidBuffFormat );
}
}
if ( (result != inContinue->pResult) && (result != nil) )
{
ldap_msgfree( result );
result = nil;
}
}
catch ( sInt32 err )
{
siResult = err;
}
if (attrs != nil)
{
int aIndex = 0;
while (attrs[aIndex] != nil)
{
free(attrs[aIndex]);
attrs[aIndex] = nil;
aIndex++;
}
free(attrs);
attrs = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
if (aRecData != nil)
{
delete (aRecData);
aRecData = nil;
}
if (aAttrData != nil)
{
delete (aAttrData);
aAttrData = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::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 (offset + 2 > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usTypeLen, pData, 2 );
pData += 2;
offset += 2;
pRecType = pData;
pData += usTypeLen;
offset += usTypeLen;
if (offset + 2 > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usNameLen, pData, 2 );
pData += 2;
offset += 2;
pRecName = pData;
pData += usNameLen;
offset += usNameLen;
if (offset + 2 > buffLen) 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;
gLDAPContextTable->AddItem( inData->fOutAttrListRef, pContext );
inData->fOutRecEntryPtr = pRecEntry;
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::GetTheseAttributes ( char *inRecType,
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 = nil;
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;
uInt32 literalLength = 0;
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, "/LDAPv3/" );
::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, "/LDAPv3/" );
::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( inRecType, kDS1AttrPassword, inContext->fConfigTableIndex, 1, pConfigFromXML, true );
numStdAttributes = 1;
pStdAttrType = GetNextStdAttrType( inRecType, inContext->fConfigTableIndex, numStdAttributes );
while ( pStdAttrType != nil )
{
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( inRecType, pStdAttrType, inContext->fConfigTableIndex, numAttributes, pConfigFromXML );
bAtLeastOneTypeValid = false;
bTypeFound = false;
while ( pLDAPAttrType != nil )
{
if (pLDAPAttrType[0] == '#') {
if (!bTypeFound)
{
aTmp2Data->Clear();
outCount++;
aTmp2Data->AppendShort( ::strlen( pStdAttrType ) );
aTmp2Data->AppendString( pStdAttrType );
bTypeFound = true;
valCount = 0;
aTmpData->Clear();
}
bAtLeastOneTypeValid = true;
literalLength = strlen(pLDAPAttrType) - 1;
if ( (inAttrOnly == false) && (literalLength > 0) )
{
valCount++;
aTmpData->AppendLong( literalLength );
aTmpData->AppendBlock( pLDAPAttrType + 1, literalLength );
} }
else
{
for ( pAttr = ldap_first_attribute (inContext->fHost, inResult, &ber );
pAttr != NULL; pAttr = ldap_next_attribute(inContext->fHost, inResult, ber ) )
{
bStripCryptPrefix = false;
if (::strcasecmp( pAttr, pLDAPAttrType ) == 0)
{
if (pLDAPPasswdAttrType != nil )
{
if ( ( ::strcasecmp( pAttr, pLDAPPasswdAttrType ) == 0 ) &&
( ::strcmp( pStdAttrType, kDS1AttrPassword ) == 0 ) )
{
bStripCryptPrefix = true;
bUsePlus = false;
free(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);
bValues = NULL;
}
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);
bValues = NULL;
}
}
if (pAttr != nil)
{
ldap_memfree( pAttr );
}
break;
} if (pAttr != nil)
{
ldap_memfree( pAttr );
}
} }
if (ber != nil)
{
ber_free( ber, 0 );
ber = nil;
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( inRecType, pStdAttrType, inContext->fConfigTableIndex, numAttributes, pConfigFromXML );
}
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( inRecType, 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);
bValues = NULL;
}
}
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 );
ber = nil;
}
} }
else {
bStripCryptPrefix = false;
numAttributes = 1;
if (::strcmp( kDS1AttrPasswordPlus, pAttrType ) == 0)
{
bStripCryptPrefix = true;
pLDAPAttrType = MapAttrToLDAPType( inRecType, kDS1AttrPassword, inContext->fConfigTableIndex, numAttributes, pConfigFromXML );
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( inRecType, pAttrType, inContext->fConfigTableIndex, numAttributes, pConfigFromXML );
bAtLeastOneTypeValid = false;
bTypeFound = false;
}
while ( pLDAPAttrType != nil )
{
bAtLeastOneTypeValid = true;
if (!bTypeFound)
{
aTmp2Data->Clear();
outCount++;
aTmp2Data->AppendShort( ::strlen( pAttrType ) );
aTmp2Data->AppendString( pAttrType );
bTypeFound = true;
valCount = 0;
aTmpData->Clear();
}
if (pLDAPAttrType[0] == '#') {
literalLength = strlen(pLDAPAttrType) - 1;
if ( (inAttrOnly == false) && (literalLength > 0) )
{
valCount++;
aTmpData->AppendLong( literalLength );
aTmpData->AppendBlock( pLDAPAttrType + 1, literalLength );
} }
else
{
if (( inAttrOnly == false ) &&
(( bValues = ldap_get_values_len (inContext->fHost, inResult, pLDAPAttrType )) != 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);
bValues = NULL;
}
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);
bValues = NULL;
}
} }
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( inRecType, pAttrType, inContext->fConfigTableIndex, numAttributes, pConfigFromXML );
}
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 ( pLDAPPasswdAttrType != nil )
{
free(pLDAPPasswdAttrType);
pLDAPPasswdAttrType = nil;
}
if ( aTmpData != nil )
{
delete( aTmpData );
aTmpData = nil;
}
if ( aTmp2Data != nil )
{
delete( aTmp2Data );
aTmp2Data = nil;
}
return( siResult );
}
char *CLDAPv3PlugIn::GetRecordName ( char *inRecType,
LDAPMessage *inResult,
sLDAPContextData *inContext,
sInt32 &errResult )
{
char *recName = nil;
char *pLDAPAttrType = nil;
struct berval **bValues;
int numAttributes = 1;
bool bTypeFound = false;
try
{
if ( inContext == nil ) throw( (sInt32)eDSBadContextData );
errResult = eDSNoErr;
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( inRecType, kDSNAttrRecordName, inContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
if (pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttrListRef);
bTypeFound = false;
while ( ( pLDAPAttrType != nil ) && (!bTypeFound) )
{
if ( ( bValues = ldap_get_values_len(inContext->fHost, inResult, pLDAPAttrType )) != NULL )
{
recName = new char[1 + bValues[0]->bv_len];
::strcpy( recName, bValues[0]->bv_val );
bTypeFound = true;
ldap_value_free_len(bValues);
bValues = NULL;
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( inRecType, kDSNAttrRecordName, inContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
} if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
}
catch ( sInt32 err )
{
errResult = err;
}
return( recName );
}
char* CLDAPv3PlugIn::MapAttrToLDAPType ( char *inRecType, char *inAttrType, uInt32 inConfigTableIndex, int inIndex, CLDAPv3Configs *inConfigFromXML, bool bSkipLiteralMappings )
{
char *outResult = nil;
uInt32 uiStrLen = 0;
uInt32 uiNativeLen = ::strlen( kDSNativeAttrTypePrefix );
uInt32 uiStdLen = ::strlen( kDSStdAttrTypePrefix );
sLDAPConfigData *pConfig = nil;
int aIndex = inIndex;
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)
{
if (inConfigFromXML != nil)
{
if ( (pConfig->fRecordTypeMapCFArray == 0) && (pConfig->fAttrTypeMapCFArray == 0) )
{
}
if (bSkipLiteralMappings)
{
do
{
outResult = inConfigFromXML->ExtractAttrMap(inRecType, inAttrType, pConfig->fRecordTypeMapCFArray, pConfig->fAttrTypeMapCFArray, aIndex );
aIndex++;
}
while ( (outResult != nil) && (outResult[0] == '#') );
}
else
{
outResult = inConfigFromXML->ExtractAttrMap(inRecType, inAttrType, pConfig->fRecordTypeMapCFArray, pConfig->fAttrTypeMapCFArray, inIndex );
}
}
}
}
} else
{
if ( inIndex == 1 )
{
outResult = new char[ 1 + ::strlen( inAttrType ) ];
::strcpy( outResult, inAttrType );
}
} }
return( outResult );
}
char** CLDAPv3PlugIn::MapAttrToLDAPTypeArray ( char *inRecType, char *inAttrType, uInt32 inConfigTableIndex, CLDAPv3Configs *inConfigFromXML )
{
char **outResult = nil;
uInt32 uiStrLen = 0;
uInt32 uiNativeLen = ::strlen( kDSNativeAttrTypePrefix );
uInt32 uiStdLen = ::strlen( kDSStdAttrTypePrefix );
sLDAPConfigData *pConfig = nil;
int countNative = 0;
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)
{
if (inConfigFromXML != nil)
{
if ( (pConfig->fRecordTypeMapCFArray == 0) && (pConfig->fAttrTypeMapCFArray == 0) )
{
}
char *singleMap = nil;
int aIndex = 1;
int usedIndex = 0;
countNative = inConfigFromXML->AttrMapsCount(inRecType, inAttrType, pConfig->fRecordTypeMapCFArray, pConfig->fAttrTypeMapCFArray);
if (countNative > 0)
{
outResult = (char **)::calloc( countNative + 1, sizeof(char *) );
do
{
singleMap = inConfigFromXML->ExtractAttrMap(inRecType, inAttrType, pConfig->fRecordTypeMapCFArray, pConfig->fAttrTypeMapCFArray, aIndex );
if (singleMap != nil)
{
if (singleMap[0] != '#')
{
outResult[usedIndex] = singleMap; usedIndex++;
}
else {
free(singleMap);
}
}
aIndex++;
}
while (singleMap != nil);
}
}
}
}
} else
{
outResult = (char **)::calloc( 2, sizeof(char *) );
*outResult = new char[ 1 + ::strlen( inAttrType ) ];
::strcpy( *outResult, inAttrType );
} }
return( outResult );
}
char** CLDAPv3PlugIn::MapAttrListToLDAPTypeArray ( char *inRecType, CAttributeList *inAttrTypeList, uInt32 inConfigTableIndex )
{
char **outResult = nil;
char **mvResult = nil;
uInt32 uiStrLen = 0;
uInt32 uiNativeLen = ::strlen( kDSNativeAttrTypePrefix );
uInt32 uiStdLen = ::strlen( kDSStdAttrTypePrefix );
sLDAPConfigData *pConfig = nil;
int countNative = 0;
char *pAttrType = nil;
sInt32 attrTypeIndex = 1;
while ( inAttrTypeList->GetAttribute( attrTypeIndex++, &pAttrType ) == eDSNoErr )
{
if ( ( strcmp(pAttrType,kDSAttributesAll) == 0 ) ||
( strcmp(pAttrType,kDSAttributesNativeAll) == 0 ) ||
( strcmp(pAttrType,kDSAttributesStandardAll) == 0 ) )
{
if (outResult != nil)
{
for (int ourIndex=0; ourIndex < countNative; ourIndex++) {
free(outResult[ourIndex]);
outResult[ourIndex] = nil;
}
free(outResult);
}
return(nil);
}
uiStrLen = ::strlen( pAttrType );
if ( ::strncmp( pAttrType, kDSNativeAttrTypePrefix, uiNativeLen ) == 0 )
{
if ( uiStrLen > uiNativeLen )
{
uiStrLen = uiStrLen - uiNativeLen;
if (outResult != nil)
{
mvResult = outResult;
outResult = (char **)::calloc( countNative + 2, sizeof( char * ) );
for (int oldIndex=0; oldIndex < countNative; oldIndex++) {
outResult[oldIndex] = mvResult[oldIndex];
}
}
else
{
outResult = (char **)::calloc( 2, sizeof( char * ) );
}
outResult[countNative] = new char[ uiStrLen + 1 ];
::strcpy( outResult[countNative], pAttrType + uiNativeLen );
countNative++;
if (mvResult != nil)
{
free(mvResult);
mvResult = nil;
}
}
} else if ( ::strncmp( pAttrType, kDSStdAttrTypePrefix, uiStdLen ) == 0 )
{
if (( inConfigTableIndex < gConfigTableLen) && ( inConfigTableIndex >= 0 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inConfigTableIndex );
if (pConfig != nil)
{
if (pConfigFromXML != nil)
{
if ( (pConfig->fRecordTypeMapCFArray == 0) && (pConfig->fAttrTypeMapCFArray == 0) )
{
}
char *singleMap = nil;
int aIndex = 1;
int mapCount = 0;
int usedMapCount= 0;
mapCount = pConfigFromXML->AttrMapsCount(inRecType, pAttrType, pConfig->fRecordTypeMapCFArray, pConfig->fAttrTypeMapCFArray);
if (mapCount > 0)
{
if (outResult != nil)
{
mvResult = outResult;
outResult = (char **)::calloc( countNative + mapCount + 1, sizeof( char * ) );
for (int oldIndex=0; oldIndex < countNative; oldIndex++) {
outResult[oldIndex] = mvResult[oldIndex];
}
}
else
{
outResult = (char **)::calloc( mapCount + 1, sizeof( char * ) );
}
do
{
singleMap = pConfigFromXML->ExtractAttrMap(inRecType, pAttrType, pConfig->fRecordTypeMapCFArray, pConfig->fAttrTypeMapCFArray, aIndex );
if (singleMap != nil)
{
if (singleMap[0] != '#')
{
outResult[countNative + usedMapCount] = singleMap; usedMapCount++;
}
else {
free(singleMap);
}
}
aIndex++;
}
while (singleMap != nil);
countNative += usedMapCount;
if (mvResult != nil)
{
free(mvResult);
mvResult = nil;
}
}
}
}
}
} else
{
if (outResult != nil)
{
mvResult = outResult;
outResult = (char **)::calloc( countNative + 2, sizeof( char * ) );
for (int oldIndex=0; oldIndex < countNative; oldIndex++) {
outResult[oldIndex] = mvResult[oldIndex];
}
}
else
{
outResult = (char **)::calloc( 2, sizeof( char * ) );
}
outResult[countNative] = new char[ strlen( pAttrType ) + 1 ];
::strcpy( outResult[countNative], pAttrType );
countNative++;
if (mvResult != nil)
{
free(mvResult);
mvResult = nil;
}
} }
return( outResult );
}
sInt32 CLDAPv3PlugIn::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 *)gLDAPContextTable->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 (offset + 2 > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrCnt, p, 2 );
if (uiIndex > usAttrCnt) throw( (sInt32)eDSInvalidIndex );
p += 2;
offset += 2;
for ( i = 1; i < uiIndex; i++ )
{
if (offset + 4 > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen, p, 4 );
p += 4 + usAttrLen;
offset += 4 + usAttrLen;
}
uiOffset = offset;
if (offset + 4 > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen, p, 4 );
p += 4;
offset += 4;
buffLen = offset + usAttrLen;
if (offset + 2 > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrTypeLen, p, 2 );
pAttrType = p + 2;
p += 2 + usAttrTypeLen;
offset += 2 + usAttrTypeLen;
if (offset + 2 > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueCnt, p, 2 );
p += 2;
offset += 2;
for ( i = 0; i < usValueCnt; i++ )
{
if (offset + 4 > buffLen) 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;
gLDAPContextTable->AddItem( inData->fOutAttrValueListRef, pValueContext );
inData->fOutAttrInfoPtr = pAttribInfo;
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::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 *)gLDAPContextTable->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 (offset + 4 > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &attrLen, p, 4 );
buffLen = attrLen + pValueContext->offset + 4;
if (buffLen > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
p += 4;
offset += 4;
if (offset + 2 > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrNameLen, p, 2 );
p += 2 + usAttrNameLen;
offset += 2 + usAttrNameLen;
if (offset + 2 > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueCnt, p, 2 );
p += 2;
offset += 2;
if (uiIndex > usValueCnt) throw( (sInt32)eDSInvalidIndex );
for ( i = 1; i < uiIndex; i++ )
{
if (offset + 4 > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 4 );
p += 4 + usValueLen;
offset += 4 + usValueLen;
}
if (offset + 4 > buffLen) 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 ( offset + usValueLen > buffLen )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 CLDAPv3PlugIn::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 CLDAPv3PlugIn::GetTheseRecords ( char *inConstRecName,
char *inConstRecType,
char *inNativeRecType,
tDirPatternMatch patternMatch,
CAttributeList *inAttrTypeList,
sLDAPContextData *inContext,
sLDAPContinueData *inContinue,
bool inAttrOnly,
CBuff *inBuff,
uInt32 &outRecCount,
bool inbOCANDGroup,
CFArrayRef inOCSearchList,
ber_int_t inScope )
{
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;
char **attrs = nil;
queryFilter = BuildLDAPQueryFilter( (char *)kDSNAttrRecordName,
inConstRecName,
patternMatch,
inContext->fConfigTableIndex,
false,
inConstRecType,
inNativeRecType,
inbOCANDGroup,
inOCSearchList,
pConfigFromXML );
outRecCount = 0;
try
{
if (inContext == nil ) throw( (sInt32)eDSInvalidContext);
if (inContinue == nil ) throw( (sInt32)eDSInvalidContinueData);
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;
}
}
if ( inContinue->msgId == 0 )
{
attrs = MapAttrListToLDAPTypeArray( inConstRecType, inAttrTypeList, inContext->fConfigTableIndex );
int numRetries = 2;
while (true)
{
sInt32 searchResult = eDSNoErr;
searchResult = DSSearchLDAP( fLDAPSessionMgr,
inContext,
inNativeRecType,
inScope,
queryFilter,
attrs,
ldapMsgId,
ldapReturnCode);
if (searchResult == eDSRecordNotFound) throw( (sInt32)eDSNoErr );
if (searchResult == eDSCannotAccessSession)
{
if (numRetries == 0)
{
throw( (sInt32)eDSCannotAccessSession );
}
else
{
RebindLDAPSession(inContext, fLDAPSessionMgr);
numRetries--;
}
}
else
{
break;
}
}
inContinue->msgId = ldapMsgId;
} else
{
ldapMsgId = inContinue->msgId;
}
if ( (inContinue->fTotalRecCount < inContinue->fLimitRecSearch) || (inContinue->fLimitRecSearch == 0) )
{
if (inContinue->pResult != nil)
{
result = inContinue->pResult;
ldapReturnCode = LDAP_RES_SEARCH_ENTRY;
}
else
{
DSGetSearchLDAPResult ( fLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
false);
}
}
while ( ( (ldapReturnCode == LDAP_RES_SEARCH_ENTRY) || (ldapReturnCode == LDAP_RES_SEARCH_RESULT) )
&& !(bufferFull)
&& ( (inContinue->fTotalRecCount < inContinue->fLimitRecSearch) ||
(inContinue->fLimitRecSearch == 0) ) )
{
if (ldapReturnCode == LDAP_RES_SEARCH_ENTRY)
{
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( inConstRecType, 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( inConstRecType, 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;
inContinue->msgId = ldapMsgId;
inContinue->pResult = result;
}
else if ( siResult == eDSNoErr )
{
ldap_msgfree( result );
result = nil;
inContinue->msgId = 0;
outRecCount++; inContinue->fTotalRecCount++;
inContinue->pResult = nil;
DSGetSearchLDAPResult ( fLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
false);
}
else
{
inContinue->msgId = 0;
inContinue->pResult = nil;
throw( (sInt32)eDSInvalidBuffFormat );
}
}
if ( (result != inContinue->pResult) && (result != nil) )
{
ldap_msgfree( result );
result = nil;
}
}
catch ( sInt32 err )
{
siResult = err;
}
if (attrs != nil)
{
int aIndex = 0;
while (attrs[aIndex] != nil)
{
free(attrs[aIndex]);
attrs[aIndex] = nil;
aIndex++;
}
free(attrs);
attrs = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
if (aAttrData != nil)
{
delete (aAttrData);
aAttrData = nil;
}
if (aRecData != nil)
{
delete (aRecData);
aRecData = nil;
}
return( siResult );
}
char *CLDAPv3PlugIn::BuildLDAPQueryFilter ( char *inConstAttrType,
char *inConstAttrName,
tDirPatternMatch patternMatch,
uInt32 inConfigTableIndex,
bool useWellKnownRecType,
char *inRecType,
char *inNativeRecType,
bool inbOCANDGroup,
CFArrayRef inOCSearchList,
CLDAPv3Configs *inConfigFromXML )
{
char *queryFilter = nil;
unsigned long matchType = eDSExact;
char *nativeAttrType = nil;
uInt32 recNameLen = 0;
int numAttributes = 1;
CFMutableStringRef cfStringRef = nil;
CFMutableStringRef cfQueryStringRef = nil;
char *escapedName = nil;
uInt32 escapedIndex = 0;
uInt32 originalIndex = 0;
bool bOnceThru = false;
uInt32 offset = 3;
uInt32 callocLength = 0;
bool objClassAdded = false;
bool bGetAllDueToLiteralMapping = false;
cfQueryStringRef = CFStringCreateMutable(kCFAllocatorDefault, 0);
if ( (inRecType != nil) && (inNativeRecType != nil) )
{
if (strncmp(inRecType,kDSStdRecordTypePrefix,strlen(kDSStdRecordTypePrefix)) == 0)
{
if (inOCSearchList != nil)
{
for ( int iOCIndex = 0; iOCIndex < CFArrayGetCount(inOCSearchList); iOCIndex++ )
{
CFStringRef ocString;
ocString = (CFStringRef)::CFArrayGetValueAtIndex( inOCSearchList, iOCIndex );
if (ocString != nil)
{
if (!objClassAdded)
{
objClassAdded = true;
if (inbOCANDGroup)
{
CFStringAppendCString(cfQueryStringRef,"(&", kCFStringEncodingUTF8);
}
else
{
CFStringAppendCString(cfQueryStringRef,"(&(|", kCFStringEncodingUTF8);
}
}
CFStringAppendCString(cfQueryStringRef, "(objectclass=", kCFStringEncodingUTF8);
CFStringAppend(cfQueryStringRef, ocString);
CFStringAppendCString(cfQueryStringRef, ")", kCFStringEncodingUTF8);
}
} if (CFStringGetLength(cfQueryStringRef) != 0)
{
if (!inbOCANDGroup)
{
CFStringAppendCString(cfQueryStringRef,")", kCFStringEncodingUTF8);
}
}
}
} }
if ( (CFStringGetLength(cfQueryStringRef) == 0) && (inConstAttrName == nil) )
{
CFStringAppendCString(cfQueryStringRef,"(&(objectclass=*)", kCFStringEncodingUTF8);
objClassAdded = true;
}
if ( (patternMatch == eDSCompoundExpression) ||
(patternMatch == eDSiCompoundExpression) )
{ cfStringRef = ParseCompoundExpression(inConstAttrName, inRecType, inConfigTableIndex, inConfigFromXML);
if (cfStringRef != nil)
{
CFStringAppend(cfQueryStringRef, cfStringRef);
CFRelease(cfStringRef);
cfStringRef = nil;
}
}
else
{
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;
}
cfStringRef = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("(|"));
numAttributes = 1;
nativeAttrType = MapAttrToLDAPType( inRecType, inConstAttrType, inConfigTableIndex, numAttributes, inConfigFromXML, false );
if (nativeAttrType == nil) {
nativeAttrType = new char[ 3 ];
::strcpy(nativeAttrType, "cn");
}
while ( nativeAttrType != nil )
{
if (nativeAttrType[0] == '#') {
if (strlen(nativeAttrType) > 1)
{
if (DoesThisMatch(escapedName, nativeAttrType+1, patternMatch))
{
if (CFStringGetLength(cfQueryStringRef) == 0)
{
CFStringAppendCString(cfQueryStringRef,"(&(objectclass=*)", kCFStringEncodingUTF8);
objClassAdded = true;
}
bGetAllDueToLiteralMapping = true;
free(nativeAttrType);
nativeAttrType = nil;
continue;
}
}
}
else
{
if (bOnceThru)
{
if (useWellKnownRecType)
{
bOnceThru = false;
break;
}
offset = 0;
}
matchType = (unsigned long) (patternMatch);
switch (matchType)
{
case eDSStartsWith:
case eDSiStartsWith:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, nativeAttrType, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,"=", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, escapedName, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,"*)", kCFStringEncodingUTF8);
bOnceThru = true;
break;
case eDSEndsWith:
case eDSiEndsWith:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, nativeAttrType, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,"=*", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, escapedName, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,")", kCFStringEncodingUTF8);
bOnceThru = true;
break;
case eDSContains:
case eDSiContains:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, nativeAttrType, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,"=*", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, escapedName, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,"*)", kCFStringEncodingUTF8);
bOnceThru = true;
break;
case eDSWildCardPattern:
case eDSiWildCardPattern:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, nativeAttrType, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,"=", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, inConstAttrName, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,")", kCFStringEncodingUTF8);
bOnceThru = true;
break;
case eDSRegularExpression:
case eDSiRegularExpression:
CFStringAppendCString(cfStringRef, inConstAttrName, kCFStringEncodingUTF8);
bOnceThru = true;
break;
case eDSExact:
case eDSiExact:
default:
CFStringAppendCString(cfStringRef,"(", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, nativeAttrType, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,"=", kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef, escapedName, kCFStringEncodingUTF8);
CFStringAppendCString(cfStringRef,")", kCFStringEncodingUTF8);
bOnceThru = true;
break;
} }
if (nativeAttrType != nil)
{
free(nativeAttrType);
nativeAttrType = nil;
}
numAttributes++;
nativeAttrType = MapAttrToLDAPType( inRecType, inConstAttrType, inConfigTableIndex, numAttributes, inConfigFromXML, false );
}
if (!bGetAllDueToLiteralMapping)
{
if (cfStringRef != nil)
{
if (offset == 3)
{
CFRange aRangeToDelete;
aRangeToDelete.location = 1;
aRangeToDelete.length = 2;
CFStringDelete(cfStringRef, aRangeToDelete);
}
else
{
CFStringAppendCString(cfStringRef,")", kCFStringEncodingUTF8);
}
CFStringAppend(cfQueryStringRef, cfStringRef);
}
}
if (cfStringRef != nil)
{
CFRelease(cfStringRef);
cfStringRef = nil;
}
if (escapedName != nil)
{
free(escapedName);
escapedName = nil;
}
} }
if (objClassAdded)
{
CFStringAppendCString(cfQueryStringRef,")", kCFStringEncodingUTF8);
}
if (CFStringGetLength(cfQueryStringRef) != 0)
{
callocLength = (uInt32) CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfQueryStringRef), kCFStringEncodingUTF8) + 1;
queryFilter = (char *) calloc(1, callocLength);
CFStringGetCString( cfQueryStringRef, queryFilter, callocLength, kCFStringEncodingUTF8 );
}
if (cfQueryStringRef != nil)
{
CFRelease(cfQueryStringRef);
cfQueryStringRef = nil;
}
return (queryFilter);
}
CFMutableStringRef CLDAPv3PlugIn::ParseCompoundExpression ( char *inConstAttrName, char *inRecType, uInt32 inConfigTableIndex, CLDAPv3Configs *inConfigFromXML )
{
CFMutableStringRef outExpression = NULL;
char *ourExpressionPtr= nil;
char *ourExp = nil;
char *attrExpression = nil;
uInt32 numChars = 0;
bool bNotDone = true;
char *attrType = nil;
char *pattMatch = nil;
bool bMultiMap = false;
if ( ( inConstAttrName != nil ) && ( inRecType != nil ) )
{
ourExpressionPtr = (char *) calloc(1, strlen(inConstAttrName) + 1);
if (ourExpressionPtr != nil)
{
ourExp = ourExpressionPtr;
strcpy(ourExpressionPtr, inConstAttrName);
outExpression = CFStringCreateMutable(kCFAllocatorDefault, 0);
numChars = strspn(ourExpressionPtr,LDAPCOMEXPSPECIALCHARS); if (numChars > 0)
{
attrExpression = (char *) calloc(1, numChars + 1);
if (attrExpression != nil)
{
strncpy(attrExpression, ourExpressionPtr, numChars);
CFStringAppendCString(outExpression, attrExpression, kCFStringEncodingUTF8);
ourExpressionPtr = ourExpressionPtr + numChars;
free(attrExpression);
attrExpression = nil;
}
}
while (bNotDone)
{
bMultiMap = false;
numChars = 0;
numChars = strcspn(ourExpressionPtr,LDAPCOMEXPSPECIALCHARS); if (numChars > 0) {
attrExpression = (char *) calloc(1, numChars + 1);
if (attrExpression != nil)
{
strncpy(attrExpression, ourExpressionPtr, numChars);
ourExpressionPtr = ourExpressionPtr + numChars;
attrType = strsep(&attrExpression,"=");
pattMatch= strsep(&attrExpression,"=");
if ((attrType != nil) && (pattMatch != nil) ) {
char *pLDAPAttrType = nil;
int numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( inRecType, attrType, inConfigTableIndex, numAttributes, inConfigFromXML, true );
if ( pLDAPAttrType != nil)
{
if ( (strcasecmp(attrType, pLDAPAttrType) == 0) || (strncmp(attrType, kDSNativeAttrTypePrefix, strlen(kDSNativeAttrTypePrefix)) == 0) ) {
CFStringAppendCString(outExpression, pLDAPAttrType, kCFStringEncodingUTF8);
CFStringAppendCString(outExpression, "=", kCFStringEncodingUTF8);
CFStringAppendCString(outExpression, pattMatch, kCFStringEncodingUTF8);
free(pLDAPAttrType);
pLDAPAttrType = nil;
}
else
{
CFStringAppendCString(outExpression, "|", kCFStringEncodingUTF8); bMultiMap = true; }
}
while(pLDAPAttrType != nil)
{
CFStringAppendCString(outExpression, "(", kCFStringEncodingUTF8); CFStringAppendCString(outExpression, pLDAPAttrType, kCFStringEncodingUTF8);
CFStringAppendCString(outExpression, "=", kCFStringEncodingUTF8);
CFStringAppendCString(outExpression, pattMatch, kCFStringEncodingUTF8); numAttributes++;
free(pLDAPAttrType);
pLDAPAttrType = nil;
pLDAPAttrType = MapAttrToLDAPType( inRecType, attrType, inConfigTableIndex, numAttributes, inConfigFromXML, true );
if (pLDAPAttrType != nil)
{
CFStringAppendCString(outExpression, ")", kCFStringEncodingUTF8);
}
}
if (bMultiMap)
{
CFStringAppendCString(outExpression, ")", kCFStringEncodingUTF8);
}
} free(attrExpression);
attrExpression = nil;
} } else
{
bNotDone = false;
}
numChars = 0;
numChars = strspn(ourExpressionPtr,LDAPCOMEXPSPECIALCHARS); if (numChars > 0)
{
attrExpression = (char *) calloc(1, numChars + 1);
if (attrExpression != nil)
{
strncpy(attrExpression, ourExpressionPtr, numChars);
CFStringAppendCString(outExpression, attrExpression, kCFStringEncodingUTF8);
ourExpressionPtr = ourExpressionPtr + numChars;
free(attrExpression);
attrExpression = nil;
}
}
}
free(ourExp);
ourExp = nil;
} }
if (outExpression != NULL)
{
if (CFStringGetLength(outExpression) < 3) {
CFRelease(outExpression);
outExpression = NULL;
}
}
return( outExpression );
}
sInt32 CLDAPv3PlugIn::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;
sLDAPConfigData *pConfig = nil;
try
{
if ( inData == nil ) throw( (sInt32) eMemoryError );
pContext = (sLDAPContextData *)gLDAPContextTable->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( "LDAPv3" ) );
aTmpData->AppendString( (char *)"LDAPv3" );
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( "ReadWrite" ) );
aTmpData->AppendString( "ReadWrite" );
}
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) && (pContext->fUserName != nil) )
{
tmpStr = new char[1+::strlen(pContext->fUserName)];
::strcpy( tmpStr, pContext->fUserName );
}
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();
}
if ( ::strcmp( pAttrName, kDSNAttrDefaultLDAPPaths ) == 0 )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDSNAttrDefaultLDAPPaths ) );
aTmpData->AppendString( (char *)kDSNAttrDefaultLDAPPaths );
if ( inData->fInAttrInfoOnly == false )
{
aTmpData->AppendShort( fDefaultLDAPNodeCount );
for ( uInt32 defLDAPIndex = 0; defLDAPIndex < fDefaultLDAPNodeCount; defLDAPIndex++ )
{
if (pDefaultLDAPNodes[defLDAPIndex] != nil)
{
aTmpData->AppendLong( strlen( pDefaultLDAPNodes[defLDAPIndex] ) );
aTmpData->AppendString( pDefaultLDAPNodes[defLDAPIndex] );
}
}
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
if ((::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, "kDS1AttrDistinguishedName" ) == 0) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( "kDS1AttrDistinguishedName" ) );
aTmpData->AppendString( (char *)"kDS1AttrDistinguishedName" );
if ( inData->fInAttrInfoOnly == false )
{
char *tmpStr = nil;
if (( pContext->fConfigTableIndex < gConfigTableLen) && ( pContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( pContext->fConfigTableIndex );
if (pConfig != nil)
{
if (pConfig->fName != nil)
{
tmpStr = new char[1+::strlen(pConfig->fName)];
::strcpy( tmpStr, pConfig->fName );
}
}
}
if (tmpStr == nil)
{
tmpStr = new char[1+::strlen("No Display Name")];
::strcpy( tmpStr, "No Display 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;
gLDAPContextTable->AddItem( inData->fOutAttrListRef, pAttrContext );
}
else
{
siResult = eDSBufferTooSmall;
}
}
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 CLDAPv3PlugIn::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;
bool bOCANDGroup = false;
CFArrayRef OCSearchList = nil;
ber_int_t scope = LDAP_SCOPE_SUBTREE;
try
{
pContext = (sLDAPContextData *)gLDAPContextTable->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 );
if (( pContext->fConfigTableIndex < gConfigTableLen) && ( pContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( pContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
numRecTypes = 1;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( pRecType->fBufferData, pContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, pConfigFromXML );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while ( (pLDAPRecType != nil) && (!bResultFound) )
{
queryFilter = BuildLDAPQueryFilter( (char *)kDSNAttrRecordName,
pRecName->fBufferData,
eDSExact,
pContext->fConfigTableIndex,
false,
pRecType->fBufferData,
pLDAPRecType,
bOCANDGroup,
OCSearchList,
pConfigFromXML );
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
int numRetries = 2;
while (true)
{
sInt32 searchResult = eDSNoErr;
searchResult = DSSearchLDAP( fLDAPSessionMgr,
pContext,
pLDAPRecType,
scope,
queryFilter,
NULL,
ldapMsgId,
ldapReturnCode);
if (searchResult == eDSRecordNotFound)
{
bResultFound = false;
break;
}
else if (searchResult == eDSCannotAccessSession)
{
bResultFound = false;
if (numRetries == 0)
{
throw( (sInt32)eDSCannotAccessSession );
}
else
{
RebindLDAPSession(pContext, fLDAPSessionMgr);
numRetries--;
}
}
else
{
bResultFound = true;
break;
}
}
if (bResultFound)
{
DSGetSearchLDAPResult ( fLDAPSessionMgr,
pContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
true);
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
if (pLDAPRecType != nil)
{
delete (pLDAPRecType);
pLDAPRecType = nil;
}
numRecTypes++;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( pRecType->fBufferData, pContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, pConfigFromXML );
}
if ( (bResultFound) &&
( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) )
{
pRecContext = MakeContextData();
if ( pRecContext == nil ) throw( (sInt32) eMemoryAllocError );
if (pContext->fName != nil)
{
pRecContext->fName = (char *)calloc(1, 1+::strlen(pContext->fName));
::strcpy( pRecContext->fName, pContext->fName );
}
pRecContext->fType = 2;
pRecContext->fHost = pContext->fHost;
pRecContext->fConfigTableIndex = pContext->fConfigTableIndex;
if (pRecType->fBufferData != nil)
{
pRecContext->fOpenRecordType = (char *)calloc(1, 1+::strlen(pRecType->fBufferData));
::strcpy( pRecContext->fOpenRecordType, pRecType->fBufferData );
}
if (pRecName->fBufferData != nil)
{
pRecContext->fOpenRecordName = (char *)calloc(1, 1+::strlen(pRecName->fBufferData));
::strcpy( pRecContext->fOpenRecordName, pRecName->fBufferData );
}
pRecContext->fOpenRecordDN = ldap_get_dn(pRecContext->fHost, result);
if (pContext->authCallActive)
{
pRecContext->authCallActive = true;
if (pContext->fUserName != nil)
{
pRecContext->fUserName = (char *)calloc(1, 1+::strlen(pContext->fUserName));
::strcpy( pRecContext->fUserName, pContext->fUserName );
}
if (pContext->fAuthCredential != nil)
{
if ( (pContext->fAuthType == nil) || (strcmp(pContext->fAuthType,kDSStdAuthClearText) == 0) )
{
char *aPassword = nil;
aPassword = (char *)calloc(1, 1+::strlen((char *)(pContext->fAuthCredential)));
::strcpy( aPassword, (char *)(pContext->fAuthCredential) );
pRecContext->fAuthCredential = (void *)aPassword;
}
}
if (pContext->fAuthType != nil)
{
pRecContext->fAuthType = (char *)calloc(1, 1+::strlen(pContext->fAuthType));
::strcpy( pRecContext->fAuthType, pContext->fAuthType );
}
}
gLDAPContextTable->AddItem( inData->fOutRecRef, pRecContext );
} }
catch ( sInt32 err )
{
siResult = err;
}
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
if ( result != nil )
{
ldap_msgfree( result );
result = nil;
}
if ( pLDAPRecType != nil )
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::CloseRecord ( sCloseRecord *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
try
{
pContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
gLDAPContextTable->RemoveItem( inData->fInRecRef );
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::FlushRecord ( sFlushRecord *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
try
{
pContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::DeleteRecord ( sDeleteRecord *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pRecContext = nil;
try
{
pRecContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pRecContext == nil ) throw( (sInt32)eDSBadContextData );
if ( pRecContext->fOpenRecordDN == nil ) throw( (sInt32)eDSNullRecName );
LDAP *aHost = fLDAPSessionMgr.LockSession(pRecContext);
if ( ldap_delete_s( aHost, pRecContext->fOpenRecordDN) != LDAP_SUCCESS )
{
siResult = eDSPermissionError;
}
fLDAPSessionMgr.UnLockSession(pRecContext);
gLDAPContextTable->RemoveItem( inData->fInRecRef );
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::AddAttribute( sAddAttribute *inData )
{
sInt32 siResult = eDSNoErr;
siResult = AddValue( inData->fInRecRef, inData->fInNewAttr, inData->fInFirstAttrValue );
return( siResult );
}
sInt32 CLDAPv3PlugIn::AddAttributeValue( sAddAttributeValue *inData )
{
sInt32 siResult = eDSNoErr;
siResult = AddValue( inData->fInRecRef, inData->fInAttrType, inData->fInAttrValue );
return( siResult );
}
sInt32 CLDAPv3PlugIn::RemoveAttribute ( sRemoveAttribute *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pRecContext = nil;
int numAttributes = 1;
char *pLDAPAttrType = nil;
LDAPMod *mods[2];
int ldapReturnCode = 0;
try
{
pRecContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pRecContext == nil ) throw( (sInt32)eDSBadContextData );
if ( pRecContext->fOpenRecordDN == nil ) throw( (sInt32)eDSNullRecName );
if ( inData->fInAttribute->fBufferData == nil ) throw( (sInt32)eDSNullAttributeType );
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, inData->fInAttribute->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
mods[1] = NULL;
while ( pLDAPAttrType != nil )
{
{
LDAPMod mod;
mod.mod_op = LDAP_MOD_DELETE;
mod.mod_type = pLDAPAttrType;
mod.mod_values = NULL;
mods[0] = &mod;
LDAP *aHost = fLDAPSessionMgr.LockSession(pRecContext);
ldapReturnCode = ldap_modify_s( aHost, pRecContext->fOpenRecordDN, mods);
fLDAPSessionMgr.UnLockSession(pRecContext);
if ( ( ldapReturnCode == LDAP_INSUFFICIENT_ACCESS ) || ( ldapReturnCode == LDAP_INVALID_CREDENTIALS ) )
{
siResult = eDSPermissionError;
}
else if ( ldapReturnCode == LDAP_NO_SUCH_OBJECT )
{
siResult = eDSAttributeNotFound;
}
else if ( ldapReturnCode != LDAP_SUCCESS )
{
siResult = eDSSchemaError;
}
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, inData->fInAttribute->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
}
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::AddValue ( uInt32 inRecRef, tDataNodePtr inAttrType, tDataNodePtr inAttrValue )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pRecContext = nil;
char *attrValue = nil;
uInt32 attrLength = 0;
char *emptyValue = (char *)"";
struct berval bval;
struct berval *bvals[2];
int numAttributes = 1;
char *pLDAPAttrType = nil;
LDAPMod *mods[2];
int ldapReturnCode = 0;
try
{
pRecContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inRecRef );
if ( pRecContext == nil ) throw( (sInt32)eDSBadContextData );
if ( pRecContext->fOpenRecordDN == nil ) throw( (sInt32)eDSNullRecName );
if ( inAttrType->fBufferData == nil ) throw( (sInt32)eDSNullAttributeType );
if (inAttrValue == nil)
{
attrValue = emptyValue;
attrLength = 1; }
else
{
attrLength = inAttrValue->fBufferLength;
attrValue = (char *) calloc(1, 1 + attrLength);
memcpy(attrValue, inAttrValue->fBufferData, attrLength);
}
bval.bv_val = attrValue;
bval.bv_len = attrLength;
bvals[0] = &bval;
bvals[1] = NULL;
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, inAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
mods[1] = NULL;
while ( pLDAPAttrType != nil )
{
{
LDAPMod mod;
mod.mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
mod.mod_type = pLDAPAttrType;
mod.mod_bvalues = bvals;
mods[0] = &mod;
LDAP *aHost = fLDAPSessionMgr.LockSession(pRecContext);
ldapReturnCode = ldap_modify_s( aHost, pRecContext->fOpenRecordDN, mods);
fLDAPSessionMgr.UnLockSession(pRecContext);
if ( ( ldapReturnCode == LDAP_INSUFFICIENT_ACCESS ) || ( ldapReturnCode == LDAP_INVALID_CREDENTIALS ) )
{
siResult = eDSPermissionError;
}
else if ( ldapReturnCode != LDAP_SUCCESS )
{
siResult = eDSAttributeNotFound;
}
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, inAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
}
}
catch ( sInt32 err )
{
siResult = err;
}
if ((attrValue != emptyValue) && (attrValue != nil))
{
free(attrValue);
attrValue = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::SetRecordName ( sSetRecordName *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pRecContext = nil;
char *pLDAPAttrType = nil;
int ldapReturnCode = 0;
tDataNodePtr pRecName = nil;
char *ldapRDNString = nil;
uInt32 ldapRDNLength = 0;
try
{
pRecContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pRecContext == nil ) throw( (sInt32)eDSBadContextData );
pRecName = inData->fInNewRecName;
if ( pRecName == nil ) throw( (sInt32)eDSNullRecName );
if (pRecName->fBufferLength == 0) throw( (sInt32)eDSEmptyRecordNameList );
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, kDSNAttrRecordName, pRecContext->fConfigTableIndex, 1, pConfigFromXML, true );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
ldapRDNLength = strlen(pLDAPAttrType) + 1 + pRecName->fBufferLength;
ldapRDNString = (char *)calloc(1, ldapRDNLength + 1);
strcpy(ldapRDNString,pLDAPAttrType);
strcat(ldapRDNString,"=");
strcat(ldapRDNString,pRecName->fBufferData);
LDAP *aHost = fLDAPSessionMgr.LockSession(pRecContext);
ldapReturnCode = ldap_rename_s( aHost, pRecContext->fOpenRecordDN, ldapRDNString, NULL, 1, NULL, NULL);
fLDAPSessionMgr.UnLockSession(pRecContext);
if ( ( ldapReturnCode == LDAP_INSUFFICIENT_ACCESS ) || ( ldapReturnCode == LDAP_INVALID_CREDENTIALS ) )
{
siResult = eDSPermissionError;
}
else if ( ldapReturnCode != LDAP_SUCCESS )
{
siResult = eDSRecordNotFound;
}
else {
if (pRecContext->fOpenRecordName != nil)
{
free(pRecContext->fOpenRecordName);
}
pRecContext->fOpenRecordName = (char *)calloc(1, 1+::strlen(pRecName->fBufferData));
::strcpy( pRecContext->fOpenRecordName, pRecName->fBufferData );
char *newldapDN = nil;
char *pLDAPRecType = nil;
pLDAPRecType = MapRecToLDAPType( pRecContext->fOpenRecordType, pRecContext->fConfigTableIndex, 1, nil, nil, nil, pConfigFromXML );
if (pLDAPRecType != nil)
{
newldapDN = (char *) calloc(1, 1 + strlen(ldapRDNString) + 2 + strlen(pLDAPRecType));
strcpy(newldapDN,ldapRDNString);
strcat(newldapDN,", ");
strcat(newldapDN,pLDAPRecType);
if (pRecContext->fOpenRecordDN != nil)
{
free(pRecContext->fOpenRecordDN);
}
pRecContext->fOpenRecordDN = newldapDN;
}
}
}
catch ( sInt32 err )
{
siResult = err;
}
if (pLDAPAttrType != nil)
{
free(pLDAPAttrType);
pLDAPAttrType = nil;
}
if (ldapRDNString != nil)
{
free(ldapRDNString);
ldapRDNString = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::CreateRecord ( sCreateRecord *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
sLDAPContextData *pRecContext = nil;
char *pLDAPAttrType = nil;
LDAPMod *mods[128]; uInt32 modIndex = 0;
int ldapReturnCode = 0;
sLDAPConfigData *pConfig = nil;
int searchTO = 0;
tDataNodePtr pRecType = nil;
tDataNodePtr pRecName = nil;
char *pLDAPRecType = nil;
char *ldapDNString = nil;
uInt32 ldapDNLength = 0;
uInt32 ocCount = 0;
uInt32 raCount = 0;
LDAPMod ocmod;
LDAPMod rnmod;
char **ocvals = nil;
char *rnvals[2];
char *ocString = nil;
listOfStrings objectClassList;
listOfStrings reqAttrsList;
char **needsValueMarker= nil;
bool bOCANDGroup = false;
CFArrayRef OCSearchList = nil;
char *tmpBuff = nil;
CFIndex cfBuffSize = 1024;
try
{
pContext = (sLDAPContextData *)gLDAPContextTable->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 );
pLDAPAttrType = MapAttrToLDAPType( pRecType->fBufferData, kDSNAttrRecordName, pContext->fConfigTableIndex, 1, pConfigFromXML, true );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
pLDAPRecType = MapRecToLDAPType( pRecType->fBufferData, pContext->fConfigTableIndex, 1, &bOCANDGroup, &OCSearchList, nil, pConfigFromXML );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidRecordType );
ldapDNLength = strlen(pLDAPAttrType) + 1 + pRecName->fBufferLength + 2 + strlen(pLDAPRecType);
ldapDNString = (char *)calloc(1, ldapDNLength + 1);
strcpy(ldapDNString,pLDAPAttrType);
strcat(ldapDNString,"=");
strcat(ldapDNString,pRecName->fBufferData);
strcat(ldapDNString,", ");
strcat(ldapDNString,pLDAPRecType);
rnvals[0] = pRecName->fBufferData;
rnvals[1] = NULL;
rnmod.mod_op = 0;
rnmod.mod_type = pLDAPAttrType;
rnmod.mod_values = rnvals;
if ( (pRecType->fBufferData != nil) && (pLDAPRecType != nil) )
{
if (strncmp(pRecType->fBufferData,kDSStdRecordTypePrefix,strlen(kDSStdRecordTypePrefix)) == 0)
{
if (( pContext->fConfigTableIndex < gConfigTableLen) && ( pContext->fConfigTableIndex >= 0 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( pContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
if (OCSearchList != nil)
{
CFStringRef ocString;
tmpBuff = (char *)::calloc(1, 1024);
if (!bOCANDGroup)
{
ocString = (CFStringRef)::CFArrayGetValueAtIndex( OCSearchList, 0 );
if (ocString != nil)
{
CFStringGetCString(ocString, tmpBuff, cfBuffSize, kCFStringEncodingUTF8);
string ourString(tmpBuff);
objectClassList.push_back(ourString);
}
}
else
{
for ( int iOCIndex = 0; iOCIndex < CFArrayGetCount(OCSearchList); iOCIndex++ )
{
::memset(tmpBuff,0,1024);
ocString = (CFStringRef)::CFArrayGetValueAtIndex( OCSearchList, iOCIndex );
if (ocString != nil)
{
CFStringGetCString(ocString, tmpBuff, cfBuffSize, kCFStringEncodingUTF8);
string ourString(tmpBuff);
objectClassList.push_back(ourString);
}
} }
} } }
mods[0] = &rnmod;
for (uInt32 modsIndex=1; modsIndex < 128; modsIndex++)
{
mods[modsIndex] = NULL;
}
modIndex = 1;
if ( (pConfig->fObjectClassSchema == nil) && (!pConfig->bOCBuilt) )
{
fLDAPSessionMgr.GetSchema( pContext );
}
if (OCSearchList != nil)
{
if (pConfig->fObjectClassSchema != nil) {
for (listOfStringsCI iter = objectClassList.begin(); iter != objectClassList.end(); ++iter)
{
if (pConfig->fObjectClassSchema->count(*iter) != 0)
{
ObjectClassMap::iterator mapIter = pConfig->fObjectClassSchema->find(*iter);
for (AttrSetCI parentIter = mapIter->second->fParentOCs.begin(); parentIter != mapIter->second->fParentOCs.end(); ++parentIter)
{
bool addObjectClassName = true;
for (listOfStringsCI dupIter = objectClassList.begin(); dupIter != objectClassList.end(); ++dupIter)
{
if (*dupIter == *parentIter) {
addObjectClassName = false;
break;
}
}
if (addObjectClassName)
{
objectClassList.push_back(*parentIter);
}
}
}
}
for (listOfStringsCI iter = objectClassList.begin(); iter != objectClassList.end(); ++iter)
{
if (pConfig->fObjectClassSchema->count(*iter) != 0)
{
ObjectClassMap::iterator mapIter = pConfig->fObjectClassSchema->find(*iter);
for (AttrSetCI reqIter = mapIter->second->fRequiredAttrs.begin(); reqIter != mapIter->second->fRequiredAttrs.end(); ++reqIter)
{
if (*reqIter != "objectClass") {
bool addReqAttr = true;
for (listOfStringsCI dupIter = reqAttrsList.begin(); dupIter != reqAttrsList.end(); ++dupIter)
{
if (*dupIter == *reqIter) {
addReqAttr = false;
break;
}
}
if (addReqAttr)
{
reqAttrsList.push_back(*reqIter);
}
}
}
}
}
}
raCount = reqAttrsList.size();
ocCount = objectClassList.size();
ocString = (char *)calloc(1,12);
strcpy(ocString,"objectClass");
ocmod.mod_op = 0;
ocmod.mod_type = ocString;
ocmod.mod_values = nil;
ocvals = (char **)calloc(1,(ocCount+1)*sizeof(char **));
uInt32 ocValIndex = 0;
for (listOfStringsCI iter = objectClassList.begin(); iter != objectClassList.end(); ++iter)
{
const char *aString = (*iter).c_str();
ocvals[ocValIndex] = (char *)aString; ocValIndex++;
}
ocvals[ocCount] = nil;
ocmod.mod_values = ocvals;
mods[1] = &ocmod;
modIndex = 2;
}
needsValueMarker = (char **)calloc(1,2*sizeof(char *));
needsValueMarker[0] = "99";
needsValueMarker[1] = NULL;
if (raCount != 0)
{
for (listOfStringsCI addIter = reqAttrsList.begin(); addIter != reqAttrsList.end(); ++addIter)
{
if (modIndex == 127)
{
break;
}
if (strcasecmp((*addIter).c_str(), pLDAPAttrType) != 0) {
LDAPMod *aLDAPMod = (LDAPMod *)calloc(1,sizeof(LDAPMod));
aLDAPMod->mod_op = 0;
const char *aString = (*addIter).c_str();
aLDAPMod->mod_type = (char *)aString; aLDAPMod->mod_values = needsValueMarker; mods[modIndex] = aLDAPMod;
modIndex++;
}
}
}
mods[modIndex] = NULL;
LDAP *aHost = fLDAPSessionMgr.LockSession(pContext);
ldapReturnCode = ldap_add_s( aHost, ldapDNString, mods);
fLDAPSessionMgr.UnLockSession(pContext);
if ( ( ldapReturnCode == LDAP_INSUFFICIENT_ACCESS ) || ( ldapReturnCode == LDAP_INVALID_CREDENTIALS ) )
{
siResult = eDSPermissionError;
}
else if ( ldapReturnCode == LDAP_ALREADY_EXISTS )
{
siResult = eDSRecordAlreadyExists;
}
else if ( ldapReturnCode != LDAP_SUCCESS )
{
siResult = eDSRecordNotFound;
}
if ( (inData->fInOpen == true) && (siResult == eDSNoErr) )
{
pRecContext = MakeContextData();
if ( pRecContext == nil ) throw( (sInt32) eMemoryAllocError );
if (pContext->fName != nil)
{
pRecContext->fName = (char *)calloc(1, 1+::strlen(pContext->fName));
::strcpy( pRecContext->fName, pContext->fName );
}
pRecContext->fType = 2;
pRecContext->fHost = pContext->fHost;
pRecContext->fConfigTableIndex = pContext->fConfigTableIndex;
if (pRecType->fBufferData != nil)
{
pRecContext->fOpenRecordType = (char *)calloc(1, 1+::strlen(pRecType->fBufferData));
::strcpy( pRecContext->fOpenRecordType, pRecType->fBufferData );
}
if (pRecName->fBufferData != nil)
{
pRecContext->fOpenRecordName = (char *)calloc(1, 1+::strlen(pRecName->fBufferData));
::strcpy( pRecContext->fOpenRecordName, pRecName->fBufferData );
}
pRecContext->fOpenRecordDN = ldapDNString;
ldapDNString = nil;
if (pContext->authCallActive)
{
pRecContext->authCallActive = true;
if (pContext->fUserName != nil)
{
pRecContext->fUserName = (char *)calloc(1, 1+::strlen(pContext->fUserName));
::strcpy( pRecContext->fUserName, pContext->fUserName );
}
if (pContext->fAuthCredential != nil)
{
if ( (pContext->fAuthType == nil) || (strcmp(pContext->fAuthType,kDSStdAuthClearText) == 0) )
{
char *aPassword = nil;
aPassword = (char *)calloc(1, 1+::strlen((char *)(pContext->fAuthCredential)));
::strcpy( aPassword, (char *)(pContext->fAuthCredential) );
pRecContext->fAuthCredential = (void *)aPassword;
}
}
if (pContext->fAuthType != nil)
{
pRecContext->fAuthType = (char *)calloc(1, 1+::strlen(pContext->fAuthType));
::strcpy( pRecContext->fAuthType, pContext->fAuthType );
}
}
gLDAPContextTable->AddItem( inData->fOutRecRef, pRecContext );
}
}
catch ( sInt32 err )
{
siResult = err;
}
if (pLDAPAttrType != nil)
{
free(pLDAPAttrType);
pLDAPAttrType = nil;
}
if (pLDAPRecType != nil)
{
free(pLDAPRecType);
pLDAPRecType = nil;
}
if (ldapDNString != nil)
{
free(ldapDNString);
ldapDNString = nil;
}
if (needsValueMarker != nil)
{
free(needsValueMarker);
needsValueMarker = nil;
}
if (ocString != nil)
{
free(ocString);
ocString = nil;
}
if (ocvals != nil)
{
free(ocvals);
ocvals = nil;
}
uInt32 startIndex = 1;
if (OCSearchList != nil)
{
startIndex = 2;
}
for (uInt32 anIndex = startIndex; anIndex < modIndex; anIndex++)
{
free(mods[anIndex]);
mods[anIndex] = NULL;
}
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
if ( tmpBuff != nil )
{
free(tmpBuff);
tmpBuff = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::RemoveAttributeValue ( sRemoveAttributeValue *inData )
{
sInt32 siResult = eDSNoErr;
tDataNodePtr pAttrType = nil;
char *pLDAPAttrType = nil;
sLDAPContextData *pRecContext = nil;
LDAPMessage *result = nil;
struct berval **bValues = nil;
struct berval **newValues = nil;
unsigned long valCount = 0;
bool bFoundIt = false;
int numAttributes = 1;
uInt32 crcVal = 0;
LDAPMod *mods[2];
int ldapReturnCode = 0;
try
{
pRecContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pRecContext == nil ) throw( (sInt32)eDSBadContextData );
if ( pRecContext->fOpenRecordDN == nil ) throw( (sInt32)eDSNullRecName );
siResult = GetRecRefLDAPMessage( pRecContext, &result );
if ( siResult != eDSNoErr ) throw( siResult );
pAttrType = inData->fInAttrType;
if ( pAttrType == nil ) throw( (sInt32)eDSEmptyAttributeType );
if ( result != nil )
{
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
bFoundIt = false;
while ( ( pLDAPAttrType != nil ) && (!bFoundIt) )
{
valCount = 0;
if (( bValues = ldap_get_values_len (pRecContext->fHost, result, pLDAPAttrType )) != NULL)
{
for (int i = 0; bValues[i] != NULL; i++ )
{
valCount++;
}
newValues = (struct berval**) calloc(1, (valCount + 1) *sizeof(struct berval *) );
uInt32 newIndex = 0;
for (int i = 0; bValues[i] != NULL; i++ )
{
crcVal = CalcCRC( bValues[i]->bv_val );
if ( crcVal == inData->fInAttrValueID )
{
bFoundIt = true;
newValues[newIndex] = bValues[i];
newIndex++;
}
}
}
if (bFoundIt)
{
{
LDAPMod mod;
mod.mod_op = LDAP_MOD_DELETE | LDAP_MOD_BVALUES;
mod.mod_type = pLDAPAttrType;
mod.mod_bvalues = newValues;
mods[0] = &mod;
mods[1] = NULL;
LDAP *aHost = fLDAPSessionMgr.LockSession(pRecContext);
ldapReturnCode = ldap_modify_s( aHost, pRecContext->fOpenRecordDN, mods);
fLDAPSessionMgr.UnLockSession(pRecContext);
if ( ( ldapReturnCode == LDAP_INSUFFICIENT_ACCESS ) || ( ldapReturnCode == LDAP_INVALID_CREDENTIALS ) )
{
siResult = eDSPermissionError;
}
else if ( ldapReturnCode == LDAP_NO_SUCH_OBJECT )
{
siResult = eDSAttributeNotFound;
}
else if ( ldapReturnCode != LDAP_SUCCESS )
{
siResult = eDSSchemaError;
}
}
}
if (bValues != NULL)
{
ldap_value_free_len(bValues);
bValues = NULL;
}
if (newValues != NULL)
{
free(newValues); newValues = NULL;
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
}
ldap_msgfree( result );
result = nil;
} else
{
throw( (sInt32)eDSRecordNotFound ); }
}
catch ( sInt32 err )
{
siResult = err;
}
if (pLDAPAttrType != nil)
{
delete( pLDAPAttrType );
pLDAPAttrType = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::SetAttributeValue ( sSetAttributeValue *inData )
{
sInt32 siResult = eDSNoErr;
tDataNodePtr pAttrType = nil;
char *pLDAPAttrType = nil;
sLDAPContextData *pRecContext = nil;
LDAPMessage *result = nil;
unsigned long valCount = 0;
struct berval **bValues = nil;
struct berval replaceValue;
struct berval **newValues = nil;
bool bFoundIt = false;
int numAttributes = 1;
uInt32 crcVal = 0;
LDAPMod *mods[2];
int ldapReturnCode = 0;
char *attrValue = nil;
uInt32 attrLength = 0;
char *emptyValue = (char *)"";
try
{
pRecContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pRecContext == nil ) throw( (sInt32)eDSBadContextData );
if ( pRecContext->fOpenRecordDN == nil ) throw( (sInt32)eDSNullRecName );
if ( inData->fInAttrValueEntry == nil ) throw( (sInt32)eDSNullAttributeValue );
if (inData->fInAttrValueEntry->fAttributeValueData.fBufferData == NULL)
{
attrValue = emptyValue;
attrLength = 1; }
else
{
attrLength = inData->fInAttrValueEntry->fAttributeValueData.fBufferLength;
attrValue = (char *) calloc(1, 1 + attrLength);
memcpy(attrValue, inData->fInAttrValueEntry->fAttributeValueData.fBufferData, attrLength);
}
siResult = GetRecRefLDAPMessage( pRecContext, &result );
if ( siResult != eDSNoErr ) throw( siResult );
pAttrType = inData->fInAttrType;
if ( pAttrType == nil ) throw( (sInt32)eDSEmptyAttributeType );
if ( result != nil )
{
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
bFoundIt = false;
while ( ( pLDAPAttrType != nil ) && (!bFoundIt) )
{
valCount = 0;
if (( bValues = ldap_get_values_len (pRecContext->fHost, result, pLDAPAttrType )) != NULL)
{
for (int i = 0; bValues[i] != NULL; i++ )
{
valCount++;
}
newValues = (struct berval**) calloc(1, (valCount + 1) *sizeof(struct berval *) );
for (int i = 0; bValues[i] != NULL; i++ )
{
crcVal = CalcCRC( bValues[i]->bv_val );
if ( crcVal == inData->fInAttrValueEntry->fAttributeValueID )
{
bFoundIt = true;
replaceValue.bv_val = attrValue;
replaceValue.bv_len = attrLength;
newValues[i] = &replaceValue;
}
else
{
newValues[i] = bValues[i];
}
}
if (!bFoundIt) {
if (bValues != NULL)
{
ldap_value_free_len(bValues);
bValues = NULL;
}
if (newValues != NULL)
{
free(newValues); newValues = NULL;
}
siResult = eDSAttributeValueNotFound;
}
}
if (bFoundIt)
{
{
LDAPMod mod;
mod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
mod.mod_type = pLDAPAttrType;
mod.mod_bvalues = newValues;
mods[0] = &mod;
mods[1] = NULL;
LDAP *aHost = fLDAPSessionMgr.LockSession(pRecContext);
ldapReturnCode = ldap_modify_s( aHost, pRecContext->fOpenRecordDN, mods);
fLDAPSessionMgr.UnLockSession(pRecContext);
if ( ( ldapReturnCode == LDAP_INSUFFICIENT_ACCESS ) || ( ldapReturnCode == LDAP_INVALID_CREDENTIALS ) )
{
siResult = eDSPermissionError;
}
else if ( ldapReturnCode != LDAP_SUCCESS )
{
siResult = eDSRecordNotFound;
}
}
}
if (bValues != NULL)
{
ldap_value_free_len(bValues);
bValues = NULL;
}
if (newValues != NULL)
{
free(newValues); newValues = NULL;
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML, true );
}
ldap_msgfree( result );
result = nil;
} else
{
throw( (sInt32)eDSRecordNotFound ); }
}
catch ( sInt32 err )
{
siResult = err;
}
if (pLDAPAttrType != nil)
{
delete( pLDAPAttrType );
pLDAPAttrType = nil;
}
if ((attrValue != emptyValue) && (attrValue != nil))
{
free(attrValue);
attrValue = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::ReleaseContinueData ( sReleaseContinueData *inData )
{
sInt32 siResult = eDSNoErr;
if ( gLDAPContinueTable->RemoveItem( inData->fInContinueData ) != eDSNoErr )
{
siResult = eDSInvalidContext;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::CloseAttributeList ( sCloseAttributeList *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
pContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInAttributeListRef );
if ( pContext != nil )
{
gLDAPContextTable->RemoveItem( inData->fInAttributeListRef );
}
else
{
siResult = eDSInvalidAttrListRef;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::CloseAttributeValueList ( sCloseAttributeValueList *inData )
{
sInt32 siResult = eDSNoErr;
sLDAPContextData *pContext = nil;
pContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInAttributeValueListRef );
if ( pContext != nil )
{
gLDAPContextTable->RemoveItem( inData->fInAttributeValueListRef );
}
else
{
siResult = eDSInvalidAttrValueRef;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::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 *)gLDAPContextTable->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 CLDAPv3PlugIn::GetRecAttribInfo ( sGetRecAttribInfo *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiTypeLen = 0;
uInt32 uiDataLen = 0;
tDataNodePtr pAttrType = nil;
char *pLDAPAttrType = nil;
tAttributeEntryPtr pOutAttrEntry = nil;
sLDAPContextData *pRecContext = nil;
LDAPMessage *result = nil;
struct berval **bValues;
int numAttributes = 1;
bool bTypeFound = false;
int valCount = 0;
try
{
pRecContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pRecContext == nil ) throw( (sInt32)eDSBadContextData );
siResult = GetRecRefLDAPMessage( pRecContext, &result );
if ( siResult != eDSNoErr ) throw( siResult);
pAttrType = inData->fInAttrType;
if ( pAttrType == nil ) throw( (sInt32)eDSEmptyAttributeType );
if ( result != nil )
{
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
bTypeFound = false;
while ( pLDAPAttrType != nil )
{
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 ( (pLDAPAttrType[0] == '#') && (strlen(pLDAPAttrType) > 1) )
{
valCount++;
uiDataLen += (strlen(pLDAPAttrType) - 1);
}
else
{
if (( bValues = ldap_get_values_len (pRecContext->fHost, result, pLDAPAttrType )) != NULL)
{
for (int ii = 0; bValues[ii] != NULL; ii++ )
valCount++;
for (int i = 0; bValues[i] != NULL; i++ )
{
uiDataLen += bValues[i]->bv_len;
} if (bValues != NULL)
{
ldap_value_free_len(bValues);
bValues = NULL;
}
} }
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML );
}
if ( pOutAttrEntry == nil )
{
inData->fOutAttrInfoPtr = nil;
throw( (sInt32)eDSAttributeNotFound );
}
pOutAttrEntry->fAttributeValueCount = valCount;
pOutAttrEntry->fAttributeValueMaxSize = 255;
pOutAttrEntry->fAttributeDataSize = uiDataLen;
inData->fOutAttrInfoPtr = pOutAttrEntry;
ldap_msgfree( result );
result = nil;
} else
{
siResult = eDSRecordNotFound;
}
}
catch ( sInt32 err )
{
siResult = err;
}
if (pLDAPAttrType != nil)
{
delete( pLDAPAttrType );
pLDAPAttrType = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::GetRecAttrValueByIndex ( sGetRecordAttributeValueByIndex *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiDataLen = 0;
tDataNodePtr pAttrType = nil;
char *pLDAPAttrType = nil;
tAttributeValueEntryPtr pOutAttrValue = nil;
sLDAPContextData *pRecContext = nil;
LDAPMessage *result = nil;
struct berval **bValues;
unsigned long valCount = 0;
bool bFoundIt = false;
int numAttributes = 1;
uInt32 literalLength = 0;
try
{
pRecContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pRecContext == nil ) throw( (sInt32)eDSBadContextData );
siResult = GetRecRefLDAPMessage( pRecContext, &result );
if ( siResult != eDSNoErr ) throw( siResult);
pAttrType = inData->fInAttrType;
if ( pAttrType == nil ) throw( (sInt32)eDSEmptyAttributeType );
if ( result != nil )
{
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
bFoundIt = false;
while ( ( pLDAPAttrType != nil ) && (!bFoundIt) )
{
if (pLDAPAttrType[0] == '#')
{
valCount++;
literalLength = strlen(pLDAPAttrType + 1);
if ( (valCount == inData->fInAttrValueIndex) && (literalLength > 0) )
{
uiDataLen = literalLength;
pOutAttrValue = (tAttributeValueEntry *)::calloc( 1, sizeof( tAttributeValueEntry ) + uiDataLen + kBuffPad );
pOutAttrValue->fAttributeValueData.fBufferSize = uiDataLen + kBuffPad;
pOutAttrValue->fAttributeValueData.fBufferLength = uiDataLen;
pOutAttrValue->fAttributeValueID = CalcCRC( pLDAPAttrType + 1 );
::memcpy( pOutAttrValue->fAttributeValueData.fBufferData, pLDAPAttrType + 1, uiDataLen );
bFoundIt = true;
}
}
else
{
if (( bValues = ldap_get_values_len (pRecContext->fHost, result, pLDAPAttrType )) != NULL)
{
for (int i = 0; bValues[i] != NULL; i++ )
{
valCount++;
if (valCount == inData->fInAttrValueIndex)
{
uiDataLen = bValues[i]->bv_len;
pOutAttrValue = (tAttributeValueEntry *)::calloc( 1, sizeof( tAttributeValueEntry ) + uiDataLen + kBuffPad );
pOutAttrValue->fAttributeValueData.fBufferSize = uiDataLen + kBuffPad;
pOutAttrValue->fAttributeValueData.fBufferLength = uiDataLen;
if ( bValues[i]->bv_val != nil )
{
pOutAttrValue->fAttributeValueID = CalcCRC( bValues[i]->bv_val );
::memcpy( pOutAttrValue->fAttributeValueData.fBufferData, bValues[i]->bv_val, uiDataLen );
}
bFoundIt = true;
break;
} } if (bValues != NULL)
{
ldap_value_free_len(bValues);
bValues = NULL;
}
} }
if (bFoundIt)
{
inData->fOutEntryPtr = pOutAttrValue;
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML );
}
ldap_msgfree( result );
result = nil;
if (!bFoundIt)
{
if (valCount < inData->fInAttrValueIndex)
{
siResult = eDSIndexOutOfRange;
}
else
{
siResult = eDSAttributeNotFound;
}
}
} else
{
siResult = eDSRecordNotFound;
}
if (pLDAPAttrType != nil)
{
delete( pLDAPAttrType );
pLDAPAttrType = nil;
}
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::GetRecordAttributeValueByID ( sGetRecordAttributeValueByID *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiDataLen = 0;
tDataNodePtr pAttrType = nil;
char *pLDAPAttrType = nil;
tAttributeValueEntryPtr pOutAttrValue = nil;
sLDAPContextData *pRecContext = nil;
LDAPMessage *result = nil;
struct berval **bValues;
bool bFoundIt = false;
int numAttributes = 1;
uInt32 crcVal = 0;
uInt32 literalLength = 0;
try
{
pRecContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInRecRef );
if ( pRecContext == nil ) throw( (sInt32)eDSBadContextData );
siResult = GetRecRefLDAPMessage( pRecContext, &result );
if ( siResult != eDSNoErr ) throw( siResult);
pAttrType = inData->fInAttrType;
if ( pAttrType == nil ) throw( (sInt32)eDSEmptyAttributeType );
if ( result != nil )
{
numAttributes = 1;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML );
if ( pLDAPAttrType == nil ) throw( (sInt32)eDSInvalidAttributeType );
bFoundIt = false;
while ( ( pLDAPAttrType != nil ) && (!bFoundIt) )
{
if (pLDAPAttrType[0] == '#')
{
literalLength = strlen(pLDAPAttrType + 1);
if (literalLength > 0)
{
crcVal = CalcCRC( pLDAPAttrType + 1 );
if ( crcVal == inData->fInValueID )
{
uiDataLen = literalLength;
pOutAttrValue = (tAttributeValueEntry *)::calloc( 1, sizeof( tAttributeValueEntry ) + uiDataLen + kBuffPad );
pOutAttrValue->fAttributeValueData.fBufferSize = uiDataLen + kBuffPad;
pOutAttrValue->fAttributeValueData.fBufferLength = uiDataLen;
pOutAttrValue->fAttributeValueID = crcVal;
::memcpy( pOutAttrValue->fAttributeValueData.fBufferData, pLDAPAttrType + 1, uiDataLen );
bFoundIt = true;
}
}
}
else
{
if (( bValues = ldap_get_values_len (pRecContext->fHost, result, pLDAPAttrType )) != NULL)
{
for (int i = 0; bValues[i] != NULL; i++ )
{
crcVal = CalcCRC( bValues[i]->bv_val );
if ( crcVal == inData->fInValueID )
{
uiDataLen = bValues[i]->bv_len;
pOutAttrValue = (tAttributeValueEntry *)::calloc( 1, sizeof( tAttributeValueEntry ) + uiDataLen + kBuffPad );
pOutAttrValue->fAttributeValueData.fBufferSize = uiDataLen = kBuffPad;
pOutAttrValue->fAttributeValueData.fBufferLength = uiDataLen;
if ( bValues[i]->bv_val != nil )
{
pOutAttrValue->fAttributeValueID = crcVal;
::memcpy( pOutAttrValue->fAttributeValueData.fBufferData, bValues[i]->bv_val, uiDataLen );
}
bFoundIt = true;
break;
} } ldap_value_free_len(bValues);
bValues = NULL;
} }
if (bFoundIt)
{
inData->fOutEntryPtr = pOutAttrValue;
}
if (pLDAPAttrType != nil)
{
delete (pLDAPAttrType);
pLDAPAttrType = nil;
}
numAttributes++;
pLDAPAttrType = MapAttrToLDAPType( pRecContext->fOpenRecordType, pAttrType->fBufferData, pRecContext->fConfigTableIndex, numAttributes, pConfigFromXML );
}
ldap_msgfree( result );
result = nil;
} else
{
throw( (sInt32)eDSRecordNotFound ); }
if (pLDAPAttrType != nil)
{
delete( pLDAPAttrType );
pLDAPAttrType = nil;
}
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
char* CLDAPv3PlugIn::GetNextStdAttrType ( char *inRecType, uInt32 inConfigTableIndex, int &inputIndex )
{
char *outResult = nil;
sLDAPConfigData *pConfig = nil;
if (inputIndex > 0)
{
if (( inConfigTableIndex < gConfigTableLen) && ( inConfigTableIndex >= 0 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inConfigTableIndex );
if (pConfig != nil)
{
if (pConfigFromXML != nil)
{
if ( (pConfig->fRecordTypeMapCFArray == 0) && (pConfig->fAttrTypeMapCFArray == 0) )
{
}
outResult = pConfigFromXML->ExtractStdAttr(inRecType, pConfig->fRecordTypeMapCFArray, pConfig->fAttrTypeMapCFArray, inputIndex );
}
}
}
}
return( outResult );
}
sInt32 CLDAPv3PlugIn::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;
sLDAPContinueData *pLDAPContinue = nil;
CBuff *outBuff = nil;
tDataList *pTmpDataList = nil;
int numRecTypes = 1;
bool bBuffFull = false;
bool separateRecTypes = false;
uInt32 countDownRecTypes = 0;
bool bOCANDGroup = false;
CFArrayRef OCSearchList = nil;
char *aCompoundExp = " "; ber_int_t scope = LDAP_SCOPE_SUBTREE;
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 *)gLDAPContextTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
if ( inData->fIOContinueData == nil )
{
pLDAPContinue = (sLDAPContinueData *)::calloc( 1, sizeof( sLDAPContinueData ) );
gLDAPContinueTable->AddItem( pLDAPContinue, inData->fInNodeRef );
pLDAPContinue->fRecTypeIndex = 1;
pLDAPContinue->fTotalRecCount = 0;
pLDAPContinue->fLimitRecSearch = 0;
if (inData->fOutMatchRecordCount >= 0)
{
pLDAPContinue->fLimitRecSearch = inData->fOutMatchRecordCount;
}
}
else
{
pLDAPContinue = (sLDAPContinueData *)inData->fIOContinueData;
if ( gLDAPContinueTable->VerifyItem( pLDAPContinue ) == false )
{
throw( (sInt32)eDSInvalidContinueData );
}
}
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() - pLDAPContinue->fRecTypeIndex + 1;
if (cpRecTypeList->GetCount() == 0) throw( (sInt32)eDSEmptyRecordTypeList );
pattMatch = inData->fInPattMatchType;
pAttrType = inData->fInAttrType->fBufferData;
if ( (pattMatch == eDSCompoundExpression) ||
(pattMatch == eDSiCompoundExpression) )
{
pAttrType = aCompoundExp; }
else
{
if ( pAttrType == nil ) throw( (sInt32)eDSEmptyAttributeType );
}
pSearchStr = inData->fInPatt2Match->fBufferData;
if ( pSearchStr == nil ) throw( (sInt32)eDSEmptyPattern2Match );
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( pLDAPContinue->fRecTypeIndex, &pRecType ) == eDSNoErr ) && (!bBuffFull)) && (!separateRecTypes))
{
numRecTypes = 1;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( pRecType, pContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, pConfigFromXML );
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, pLDAPContinue, bAttribOnly, outBuff, uiCount, bOCANDGroup, OCSearchList, scope );
}
else
{
siResult = FindTheseRecords( pAttrType, pSearchStr, pRecType, pLDAPRecType, pattMatch, cpAttrTypeList, pContext, pLDAPContinue, bAttribOnly, outBuff, uiCount, bOCANDGroup, OCSearchList, scope );
}
if ( siResult == CBuff::kBuffFull )
{
bBuffFull = true;
inData->fIOContinueData = pLDAPContinue;
if ( ( uiCount == 0 ) && ( uiTotal == 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++;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( pRecType, pContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, pConfigFromXML );
}
}
if (!bBuffFull)
{
pRecType = nil;
pLDAPContinue->fRecTypeIndex++;
pLDAPContinue->msgId = 0;
separateRecTypes = true;
inData->fIOContinueData = pLDAPContinue;
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 (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
if ( (inData->fIOContinueData == nil) && (pLDAPContinue != nil) )
{
gLDAPContinueTable->RemoveItem( pLDAPContinue );
pLDAPContinue = nil;
}
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 CLDAPv3PlugIn::DoTheseAttributesMatch( sLDAPContextData *inContext,
char *inAttrName,
tDirPatternMatch pattMatch,
LDAPMessage *inResult)
{
char *pAttr = nil;
char *pVal = nil;
BerElement *ber = nil;
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);
bValues = NULL;
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 CLDAPv3PlugIn::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 CLDAPv3PlugIn::FindAllRecords ( char *inConstAttrName,
char *inConstRecType,
char *inNativeRecType,
tDirPatternMatch patternMatch,
CAttributeList *inAttrTypeList,
sLDAPContextData *inContext,
sLDAPContinueData *inContinue,
bool inAttrOnly,
CBuff *inBuff,
uInt32 &outRecCount,
bool inbOCANDGroup,
CFArrayRef inOCSearchList,
ber_int_t inScope )
{
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;
char *queryFilter = nil;
char **attrs = nil;
queryFilter = BuildLDAPQueryFilter( nil,
nil,
eDSAnyMatch,
inContext->fConfigTableIndex,
false,
inConstRecType,
inNativeRecType,
inbOCANDGroup,
inOCSearchList,
pConfigFromXML );
outRecCount = 0;
try
{
if (inContext == nil ) throw( (sInt32)eDSInvalidContext);
if (inContinue == nil ) throw( (sInt32)eDSInvalidContinueData);
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;
}
}
if (inContinue->msgId == 0)
{
attrs = MapAttrListToLDAPTypeArray( inConstRecType, inAttrTypeList, inContext->fConfigTableIndex );
int numRetries = 2;
while (true)
{
sInt32 searchResult = eDSNoErr;
searchResult = DSSearchLDAP( fLDAPSessionMgr,
inContext,
inNativeRecType,
inScope,
queryFilter,
attrs,
ldapMsgId,
ldapReturnCode);
if (searchResult == eDSRecordNotFound) throw( (sInt32)eDSNoErr );
if (searchResult == eDSCannotAccessSession)
{
if (numRetries == 0)
{
throw( (sInt32)eDSCannotAccessSession );
}
else
{
RebindLDAPSession(inContext, fLDAPSessionMgr);
numRetries--;
}
}
else
{
break;
}
}
inContinue->msgId = ldapMsgId;
} else
{
ldapMsgId = inContinue->msgId;
}
if ( (inContinue->fTotalRecCount < inContinue->fLimitRecSearch) || (inContinue->fLimitRecSearch == 0) )
{
if (inContinue->pResult != nil)
{
result = inContinue->pResult;
ldapReturnCode = LDAP_RES_SEARCH_ENTRY;
}
else
{
DSGetSearchLDAPResult ( fLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
false);
}
}
while ( ( (ldapReturnCode == LDAP_RES_SEARCH_ENTRY) || (ldapReturnCode == LDAP_RES_SEARCH_RESULT) )
&& !(bufferFull)
&& ( (inContinue->fTotalRecCount < inContinue->fLimitRecSearch) ||
(inContinue->fLimitRecSearch == 0) ) )
{
if (ldapReturnCode == LDAP_RES_SEARCH_ENTRY)
{
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( inConstRecType, 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( inConstRecType, 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;
inContinue->pResult = result;
}
else if ( siResult == eDSNoErr )
{
ldap_msgfree( result );
result = nil;
if (bFoundMatch)
{
outRecCount++; inContinue->fTotalRecCount++;
}
inContinue->pResult = nil;
DSGetSearchLDAPResult ( fLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
false);
}
else
{
inContinue->pResult = nil;
throw( (sInt32)eDSInvalidBuffFormat );
}
}
if ( (result != inContinue->pResult) && (result != nil) )
{
ldap_msgfree( result );
result = nil;
}
}
catch ( sInt32 err )
{
siResult = err;
}
if (attrs != nil)
{
int aIndex = 0;
while (attrs[aIndex] != nil)
{
free(attrs[aIndex]);
attrs[aIndex] = nil;
aIndex++;
}
free(attrs);
attrs = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
if ( aRecData != nil )
{
delete( aRecData );
aRecData = nil;
}
if ( aAttrData != nil )
{
delete( aAttrData );
aAttrData = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::FindTheseRecords ( char *inConstAttrType,
char *inConstAttrName,
char *inConstRecType,
char *inNativeRecType,
tDirPatternMatch patternMatch,
CAttributeList *inAttrTypeList,
sLDAPContextData *inContext,
sLDAPContinueData *inContinue,
bool inAttrOnly,
CBuff *inBuff,
uInt32 &outRecCount,
bool inbOCANDGroup,
CFArrayRef inOCSearchList,
ber_int_t inScope )
{
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;
char **attrs = nil;
queryFilter = BuildLDAPQueryFilter( inConstAttrType,
inConstAttrName,
patternMatch,
inContext->fConfigTableIndex,
false,
inConstRecType,
inNativeRecType,
inbOCANDGroup,
inOCSearchList,
pConfigFromXML );
outRecCount = 0;
try
{
if (inContext == nil ) throw( (sInt32)eDSInvalidContext);
if (inContinue == nil ) throw( (sInt32)eDSInvalidContinueData);
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;
}
}
if (inContinue->msgId == 0)
{
attrs = MapAttrListToLDAPTypeArray( inConstRecType, inAttrTypeList, inContext->fConfigTableIndex );
int numRetries = 2;
while (true)
{
sInt32 searchResult = eDSNoErr;
searchResult = DSSearchLDAP( fLDAPSessionMgr,
inContext,
inNativeRecType,
inScope,
queryFilter,
attrs,
ldapMsgId,
ldapReturnCode);
if (searchResult == eDSRecordNotFound) throw( (sInt32)eDSNoErr );
if (searchResult == eDSCannotAccessSession)
{
if (numRetries == 0)
{
throw( (sInt32)eDSCannotAccessSession );
}
else
{
RebindLDAPSession(inContext, fLDAPSessionMgr);
numRetries--;
}
}
else
{
break;
}
}
inContinue->msgId = ldapMsgId;
} else
{
ldapMsgId = inContinue->msgId;
}
if ( (inContinue->fTotalRecCount < inContinue->fLimitRecSearch) || (inContinue->fLimitRecSearch == 0) )
{
if (inContinue->pResult != nil)
{
result = inContinue->pResult;
ldapReturnCode = LDAP_RES_SEARCH_ENTRY;
}
else
{
DSGetSearchLDAPResult ( fLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
false);
}
}
while ( ( (ldapReturnCode == LDAP_RES_SEARCH_ENTRY) || (ldapReturnCode == LDAP_RES_SEARCH_RESULT) )
&& !(bufferFull)
&& ( (inContinue->fTotalRecCount < inContinue->fLimitRecSearch) ||
(inContinue->fLimitRecSearch == 0) ) )
{
if (ldapReturnCode == LDAP_RES_SEARCH_ENTRY)
{
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( inConstRecType, 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( inConstRecType, 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;
inContinue->msgId = ldapMsgId;
inContinue->pResult = result;
}
else if ( siResult == eDSNoErr )
{
ldap_msgfree( result );
inContinue->msgId = 0;
outRecCount++; inContinue->fTotalRecCount++;
inContinue->pResult = nil;
DSGetSearchLDAPResult ( fLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
false);
}
else
{
inContinue->msgId = 0;
inContinue->pResult = nil;
throw( (sInt32)eDSInvalidBuffFormat );
}
}
if ( (result != inContinue->pResult) && (result != nil) )
{
ldap_msgfree( result );
result = nil;
}
}
catch ( sInt32 err )
{
siResult = err;
}
if (attrs != nil)
{
int aIndex = 0;
while (attrs[aIndex] != nil)
{
free(attrs[aIndex]);
attrs[aIndex] = nil;
aIndex++;
}
free(attrs);
attrs = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
if ( aRecData != nil )
{
delete( aRecData );
aRecData = nil;
}
if ( aAttrData != nil )
{
delete( aAttrData );
aAttrData = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::DoAuthentication ( sDoDirNodeAuth *inData )
{
sInt32 siResult = eDSAuthFailed;
uInt32 uiAuthMethod = 0;
sLDAPContextData *pContext = nil;
sLDAPContinueData *pContinueData = NULL;
char* userName = NULL;
AuthAuthorityHandlerProc handlerProc = NULL;
try
{
pContext = (sLDAPContextData *)gLDAPContextTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSInvalidNodeRef );
if ( inData->fInAuthStepData == nil ) throw( (sInt32)eDSNullAuthStepData );
if ( inData->fIOContinueData != NULL )
{
pContinueData = (sLDAPContinueData *)inData->fIOContinueData;
if ( gLDAPContinueTable->VerifyItem( pContinueData ) == false )
{
throw( (sInt32)eDSInvalidContinueData );
}
if ( eDSInvalidContinueData == nil ) throw( (sInt32)(pContinueData->fAuthHandlerProc) );
handlerProc = (AuthAuthorityHandlerProc)(pContinueData->fAuthHandlerProc);
if (handlerProc != NULL)
{
siResult = (handlerProc)(inData->fInNodeRef, inData->fInAuthMethod, pContext,
&pContinueData, inData->fInAuthStepData,
inData->fOutAuthStepDataResponse,
inData->fInDirNodeAuthOnlyFlag,
pContinueData->fAuthAuthorityData,
pConfigFromXML, fLDAPSessionMgr);
}
}
else
{
unsigned long idx = 0;
unsigned long aaCount = 0;
char **aaArray;
siResult = GetAuthMethod( inData->fInAuthMethod, &uiAuthMethod );
if ( siResult != eDSNoErr && siResult != eDSAuthMethodNotSupported )
throw( siResult );
if ( siResult == eDSNoErr && uiAuthMethod == kAuth2WayRandom )
{
if ( inData->fInAuthStepData->fBufferLength > inData->fInAuthStepData->fBufferSize ) throw( (sInt32)eDSInvalidBuffFormat );
userName = (char*)calloc( inData->fInAuthStepData->fBufferLength + 1, 1 );
strncpy( userName, inData->fInAuthStepData->fBufferData, inData->fInAuthStepData->fBufferLength );
}
else
{
siResult = GetUserNameFromAuthBuffer( inData->fInAuthStepData, 1, &userName );
if ( siResult != eDSNoErr ) throw( siResult );
}
siResult = GetAuthAuthority( pContext,
inData->fInAuthStepData,
pConfigFromXML,
fLDAPSessionMgr,
&aaCount,
&aaArray );
if ( siResult == eDSNoErr )
{
bool bLoopAll = false;
char* aaVersion = NULL;
char* aaTag = NULL;
char* aaData = NULL;
siResult = eDSAuthMethodNotSupported;
while ( idx < aaCount &&
(siResult == eDSAuthMethodNotSupported || (bLoopAll && siResult == eDSNoErr)) )
{
siResult = ParseAuthAuthority( aaArray[idx], &aaVersion, &aaTag, &aaData );
if ( aaArray[idx] )
free( aaArray[idx] );
if (siResult != eDSNoErr) {
siResult = eDSAuthFailed;
break;
}
handlerProc = GetAuthAuthorityHandler( aaTag );
if (handlerProc != NULL) {
siResult = (handlerProc)(inData->fInNodeRef, inData->fInAuthMethod, pContext,
&pContinueData,
inData->fInAuthStepData,
inData->fOutAuthStepDataResponse,
inData->fInDirNodeAuthOnlyFlag,aaData,
pConfigFromXML, fLDAPSessionMgr);
if (pContinueData != NULL && siResult == eDSNoErr)
{
pContinueData->fAuthHandlerProc = (void*)handlerProc;
pContinueData->fAuthAuthorityData = aaData;
aaData = NULL;
break;
}
} else {
siResult = eDSAuthMethodNotSupported;
}
if (aaVersion != NULL) {
free(aaVersion);
aaVersion = NULL;
}
if (aaTag != NULL) {
free(aaTag);
aaTag = NULL;
}
if (aaData != NULL) {
free(aaData);
aaData = NULL;
}
++idx;
}
if (aaVersion != NULL) {
free(aaVersion);
aaVersion = NULL;
}
if (aaTag != NULL) {
free(aaTag);
aaTag = NULL;
}
if (aaData != NULL) {
free(aaData);
aaData = NULL;
}
if (aaArray != NULL) {
free( aaArray );
aaArray = NULL;
}
}
else
{
siResult = DoBasicAuth(inData->fInNodeRef,inData->fInAuthMethod, pContext,
&pContinueData, inData->fInAuthStepData,
inData->fOutAuthStepDataResponse,
inData->fInDirNodeAuthOnlyFlag,NULL,
pConfigFromXML, fLDAPSessionMgr);
if (pContinueData != NULL && siResult == eDSNoErr)
{
pContinueData->fAuthHandlerProc = (void*)CLDAPv3PlugIn::DoBasicAuth;
}
}
}
}
catch( sInt32 err )
{
siResult = err;
}
if (userName != NULL)
{
free(userName);
userName = NULL;
}
inData->fResult = siResult;
inData->fIOContinueData = pContinueData;
return( siResult );
}
sInt32 CLDAPv3PlugIn::DoPasswordServerAuth(
tDirNodeReference inNodeRef,
tDataNodePtr inAuthMethod,
sLDAPContextData* inContext,
sLDAPContinueData** inOutContinueData,
tDataBufferPtr inAuthData,
tDataBufferPtr outAuthData,
bool inAuthOnly,
char* inAuthAuthorityData,
CLDAPv3Configs *inConfigFromXML,
CLDAPNode& inLDAPSessionMgr )
{
sInt32 result = eDSAuthFailed;
sInt32 error;
uInt32 authMethod;
char *serverAddr;
char *uidStr = NULL;
long uidStrLen;
tDataBufferPtr authDataBuff = NULL;
tDataBufferPtr authDataBuffTemp = NULL;
char *nodeName = NULL;
char *userName = NULL;
char *accountId = NULL;
char *password = NULL;
sLDAPContinueData *pContinue = NULL;
tContextData continueData = NULL;
if ( !inAuthAuthorityData || *inAuthAuthorityData == '\0' )
return eDSAuthParameterError;
try
{
serverAddr = strchr( inAuthAuthorityData, ':' );
if ( serverAddr )
{
uidStrLen = serverAddr - inAuthAuthorityData;
uidStr = (char *) calloc(1, uidStrLen+1);
if ( uidStr == nil ) throw( eMemoryError );
strncpy( uidStr, inAuthAuthorityData, uidStrLen );
serverAddr++;
error = GetAuthMethod( inAuthMethod, &authMethod );
switch( authMethod )
{
case kAuth2WayRandom:
if ( inOutContinueData == nil )
throw( (sInt32)eDSNullParameter );
if ( *inOutContinueData == nil )
{
pContinue = (sLDAPContinueData *)::calloc( 1, sizeof( sLDAPContinueData ) );
gLDAPContinueTable->AddItem( pContinue, inNodeRef );
authDataBuff = ::dsDataBufferAllocatePriv( uidStrLen + 1 );
if ( authDataBuff == nil ) throw ( eMemoryError );
strcpy( authDataBuff->fBufferData, uidStr );
authDataBuff->fBufferLength = uidStrLen;
}
else
{
pContinue = *inOutContinueData;
if ( gLDAPContinueTable->VerifyItem( pContinue ) == false )
throw( (sInt32)eDSInvalidContinueData );
}
break;
case kAuthSetPasswd:
{
char* aaVersion = NULL;
char* aaTag = NULL;
char* aaData = NULL;
unsigned int idx;
sInt32 lookupResult;
char* endPtr = NULL;
error = GetUserNameFromAuthBuffer( inAuthData, 3, &userName );
if ( error != eDSNoErr ) throw( error );
if ( error != eDSNoErr ) throw( (sInt32)eDSAuthFailed );
lookupResult = eDSAuthFailed;
for ( idx = 0; idx < 0 && lookupResult == eDSAuthFailed; idx++ )
{
if (error != eDSNoErr)
lookupResult = eParameterError;
if ( error == eDSNoErr && strcmp(aaTag, "ApplePasswordServer") == 0 )
{
endPtr = strchr( aaData, ':' );
if ( endPtr == NULL )
{
lookupResult = eParameterError;
}
else
{
*endPtr = '\0';
lookupResult = eDSNoErr;
}
}
if (aaVersion != NULL) {
free(aaVersion);
aaVersion = NULL;
}
if (aaTag != NULL) {
free(aaTag);
aaTag = NULL;
}
if (lookupResult != eDSNoErr && aaData != NULL) {
free(aaData);
aaData = NULL;
}
}
if ( lookupResult != eDSNoErr ) throw( eDSAuthFailed );
error = RepackBufferForPWServer(inAuthData, uidStr, 1, &authDataBuffTemp );
if ( error != eDSNoErr ) throw( error );
error = RepackBufferForPWServer(authDataBuffTemp, aaData, 3, &authDataBuff );
if (aaData != NULL) {
free(aaData);
aaData = NULL;
}
if ( error != eDSNoErr ) throw( error );
}
break;
case kAuthClearText:
case kAuthNativeClearTextOK:
case kAuthNativeNoClearText:
{
tDataListPtr dataList = dsAuthBufferGetDataListAllocPriv(inAuthData);
if (dataList != NULL)
{
userName = dsDataListGetNodeStringPriv(dataList, 1);
password = dsDataListGetNodeStringPriv(dataList, 2);
dsDataListDeallocatePriv(dataList);
free(dataList);
dataList = NULL;
}
}
default:
error = RepackBufferForPWServer(inAuthData, uidStr, 1, &authDataBuff );
if ( error != eDSNoErr ) throw( error );
}
if ( inContext->fPWSRef == 0 )
{
error = ::dsOpenDirService( &inContext->fPWSRef );
if ( error != eDSNoErr ) throw( error );
}
if ( inContext->fPWSNodeRef == 0 )
{
nodeName = (char *)calloc(1,strlen(serverAddr)+17);
if ( nodeName == nil ) throw ( eMemoryError );
sprintf( nodeName, "/PasswordServer/%s", serverAddr );
error = PWOpenDirNode( inContext->fPWSRef, nodeName, &inContext->fPWSNodeRef );
if ( error != eDSNoErr ) throw( error );
}
if ( pContinue )
continueData = pContinue->fPassPlugContinueData;
result = dsDoDirNodeAuth( inContext->fPWSNodeRef, inAuthMethod, inAuthOnly,
authDataBuff, outAuthData, &continueData );
if ( pContinue )
pContinue->fPassPlugContinueData = continueData;
if ( (result == eDSNoErr) && (inAuthOnly == false) && (userName != NULL) && (password != NULL) )
{
LDAP* aLDAPHost = NULL;
accountId = GetDNForRecordName ( userName, inContext, inConfigFromXML, inLDAPSessionMgr );
result = inLDAPSessionMgr.AuthOpen( inContext->fName,
inContext->fHost,
accountId,
password,
kDSStdAuthClearText,
&aLDAPHost,
&(inContext->fConfigTableIndex),
true);
if (result == eDSNoErr)
{
if (inContext->fLDAPSessionMutex == nil)
{
inContext->fLDAPSessionMutex = new DSMutexSemaphore();
}
inContext->fLDAPSessionMutex->Wait();
inContext->fHost = aLDAPHost;
if (inContext->fAuthType == nil)
{
inContext->fAuthType = strdup(kDSStdAuthClearText);
}
inContext->authCallActive = true;
if (inContext->fUserName != nil)
{
free(inContext->fUserName);
inContext->fUserName = nil;
}
inContext->fUserName = strdup(accountId);
if (inContext->fAuthCredential != nil)
{
free(inContext->fAuthCredential);
inContext->fAuthCredential = nil;
}
inContext->fAuthCredential = strdup(password);
inContext->fLDAPSessionMutex->Signal();
}
else
{
result = eDSAuthFailed;
}
}
}
}
catch(sInt32 err )
{
result = err;
}
if ( nodeName )
free( nodeName );
if ( uidStr != NULL )
{
free( uidStr );
uidStr = NULL;
}
if ( userName != NULL )
{
free( userName );
userName = NULL;
}
if ( password != NULL )
{
free( password );
password = NULL;
}
if ( accountId != NULL )
{
free( accountId );
accountId = NULL;
}
if ( authDataBuff )
dsDataBufferDeallocatePriv( authDataBuff );
if ( authDataBuffTemp )
dsDataBufferDeallocatePriv( authDataBuffTemp );
return( result );
}
sInt32 CLDAPv3PlugIn::DoBasicAuth(
tDirNodeReference inNodeRef,
tDataNodePtr inAuthMethod,
sLDAPContextData* inContext,
sLDAPContinueData** inOutContinueData,
tDataBufferPtr inAuthData,
tDataBufferPtr outAuthData,
bool inAuthOnly,
char* inAuthAuthorityData,
CLDAPv3Configs *inConfigFromXML,
CLDAPNode& inLDAPSessionMgr )
{
sInt32 siResult = noErr;
UInt32 uiAuthMethod = 0;
try
{
siResult = GetAuthMethod( inAuthMethod, &uiAuthMethod );
if ( siResult == noErr )
{
switch( uiAuthMethod )
{
case kAuthCrypt:
case kAuthNativeNoClearText:
siResult = DoUnixCryptAuth( inContext, inAuthData, inConfigFromXML, inLDAPSessionMgr );
break;
case kAuthNativeClearTextOK:
if ( inAuthOnly == true )
{
siResult = DoUnixCryptAuth( inContext, inAuthData, inConfigFromXML, inLDAPSessionMgr );
if ( siResult == eDSNoErr )
{
if ( outAuthData->fBufferSize > ::strlen( kDSStdAuthCrypt ) )
{
::strcpy( outAuthData->fBufferData, kDSStdAuthCrypt );
}
}
}
if ( (siResult != eDSNoErr) || (inAuthOnly == false) )
{
siResult = DoClearTextAuth( inContext, inAuthData, inAuthOnly, inConfigFromXML, inLDAPSessionMgr );
if ( siResult == eDSNoErr )
{
if ( outAuthData->fBufferSize > ::strlen( kDSStdAuthClearText ) )
{
::strcpy( outAuthData->fBufferData, kDSStdAuthClearText );
}
}
}
break;
case kAuthClearText:
siResult = DoClearTextAuth( inContext, inAuthData, inAuthOnly, inConfigFromXML, inLDAPSessionMgr );
if ( siResult == eDSNoErr )
{
if ( outAuthData->fBufferSize > ::strlen( kDSStdAuthClearText ) )
{
::strcpy( outAuthData->fBufferData, kDSStdAuthClearText );
}
}
break;
case kAuthSetPasswd:
siResult = DoSetPassword( inContext, inAuthData, inConfigFromXML, inLDAPSessionMgr );
break;
case kAuthSetPasswdAsRoot:
siResult = DoSetPasswordAsRoot( inContext, inAuthData, inConfigFromXML, inLDAPSessionMgr );
break;
case kAuthChangePasswd:
siResult = DoChangePassword( inContext, inAuthData, inConfigFromXML, inLDAPSessionMgr );
break;
default:
siResult = eDSAuthMethodNotSupported;
break;
}
}
}
catch ( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::DoSetPassword ( sLDAPContextData *inContext, tDataBuffer *inAuthData,
CLDAPv3Configs *inConfigFromXML, CLDAPNode& inLDAPSessionMgr )
{
sInt32 siResult = eDSAuthFailed;
char *pData = nil;
char *userName = nil;
uInt32 userNameLen = 0;
char *userPwd = nil;
uInt32 userPwdLen = 0;
char *rootName = nil;
uInt32 rootNameLen = 0;
char *rootPwd = nil;
uInt32 rootPwdLen = 0;
uInt32 offset = 0;
uInt32 buffSize = 0;
uInt32 buffLen = 0;
char *accountId;
try
{
if ( inContext == nil ) throw( (sInt32)eDSAuthFailed );
if ( inAuthData == nil ) throw( (sInt32)eDSNullAuthStepData );
pData = inAuthData->fBufferData;
buffSize = inAuthData->fBufferSize;
buffLen = inAuthData->fBufferLength;
if ( buffLen > buffSize ) throw( (sInt32)eDSInvalidBuffFormat );
if ( buffLen < 4 * sizeof( unsigned long ) + 2 ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &userNameLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
if (userNameLen == 0) throw( (sInt32)eDSInvalidBuffFormat );
if (offset + userNameLen > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
userName = (char *)::calloc( 1, userNameLen + 1 );
::memcpy( userName, pData, userNameLen );
pData += userNameLen;
offset += userNameLen;
if (offset + sizeof( unsigned long ) > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &userPwdLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
if (offset + userPwdLen > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
userPwd = (char *)::calloc( 1, userPwdLen + 1 );
::memcpy( userPwd, pData, userPwdLen );
pData += userPwdLen;
offset += userPwdLen;
if (offset + sizeof( unsigned long ) > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &rootNameLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
if (rootNameLen == 0) throw( (sInt32)eDSInvalidBuffFormat );
if (rootNameLen > (buffSize - offset)) throw( (sInt32)eDSInvalidBuffFormat );
rootName = (char *)::calloc( 1, rootNameLen + 1 );
::memcpy( rootName, pData, rootNameLen );
pData += rootNameLen;
offset += rootNameLen;
if (sizeof( unsigned long ) > (buffSize - offset)) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &rootPwdLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
if (rootPwdLen > (buffSize - offset)) throw( (sInt32)eDSInvalidBuffFormat );
rootPwd = (char *)::calloc( 1, rootPwdLen + 1 );
::memcpy( rootPwd, pData, rootPwdLen );
pData += rootPwdLen;
offset += rootPwdLen;
if (rootName)
{
accountId = GetDNForRecordName ( rootName, inContext, inConfigFromXML, inLDAPSessionMgr );
}
LDAP *aLDAPHost = nil;
siResult = inLDAPSessionMgr.AuthOpen( inContext->fName,
inContext->fHost,
accountId,
rootPwd,
kDSStdAuthClearText,
&aLDAPHost,
&(inContext->fConfigTableIndex),
false);
if( siResult == eDSNoErr ) {
int rc = exop_password_create( aLDAPHost, accountId, userPwd );
if( rc != LDAP_SUCCESS ) {
rc = standard_password_create( aLDAPHost, accountId, userPwd );
}
if ( ( rc == LDAP_INSUFFICIENT_ACCESS ) || ( rc == LDAP_INVALID_CREDENTIALS ) ) {
siResult = eDSPermissionError;
}
else if ( rc == LDAP_NOT_SUPPORTED ) {
siResult = eDSAuthMethodNotSupported;
}
else if ( rc == LDAP_SUCCESS ) {
siResult = eDSNoErr;
}
else
{
siResult = eDSAuthFailed;
}
ldap_unbind(aLDAPHost);
}
else
{
siResult = eDSAuthFailed;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( userName != nil )
{
free( userName );
userName = nil;
}
if ( userPwd != nil )
{
free( userPwd );
userPwd = nil;
}
if ( rootName != nil )
{
free( rootName );
rootName = nil;
}
if ( rootPwd != nil )
{
free( rootPwd );
rootPwd = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::DoSetPasswordAsRoot ( sLDAPContextData *inContext, tDataBuffer *inAuthData,
CLDAPv3Configs *inConfigFromXML, CLDAPNode& inLDAPSessionMgr )
{
sInt32 siResult = eDSAuthFailed;
char *pData = nil;
char *userName = nil;
uInt32 userNameLen = 0;
char *newPasswd = nil;
uInt32 newPwdLen = 0;
uInt32 offset = 0;
uInt32 buffSize = 0;
uInt32 buffLen = 0;
char *accountId = nil;
try
{
if ( inContext == nil ) throw( (sInt32)eDSAuthFailed );
if ( inAuthData == nil ) throw( (sInt32)eDSNullAuthStepData );
pData = inAuthData->fBufferData;
buffSize = inAuthData->fBufferSize;
buffLen = inAuthData->fBufferLength;
if ( buffLen > buffSize ) throw( (sInt32)eDSInvalidBuffFormat );
if ( buffLen < 2 * sizeof( unsigned long ) + 1 ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &userNameLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
if (userNameLen == 0) throw( (sInt32)eDSInvalidBuffFormat );
if (userNameLen > (buffSize - offset)) throw( (sInt32)eDSInvalidBuffFormat );
userName = (char *)::calloc( 1, userNameLen + 1 );
::memcpy( userName, pData, userNameLen );
pData += userNameLen;
offset += userNameLen;
if (offset + sizeof( unsigned long ) > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &newPwdLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
if (newPwdLen > (buffSize - offset)) throw( (sInt32)eDSInvalidBuffFormat );
newPasswd = (char *)::calloc( 1, newPwdLen + 1 );
::memcpy( newPasswd, pData, newPwdLen );
pData += newPwdLen;
offset += newPwdLen;
if (userName)
{
accountId = GetDNForRecordName ( userName, inContext, inConfigFromXML, inLDAPSessionMgr );
}
LDAP *aHost = inLDAPSessionMgr.LockSession(inContext);
int rc = exop_password_create( aHost, accountId, newPasswd );
if( rc != LDAP_SUCCESS )
rc = standard_password_create( aHost, accountId, newPasswd );
inLDAPSessionMgr.UnLockSession(inContext);
if ( ( rc == LDAP_INSUFFICIENT_ACCESS ) || ( rc == LDAP_INVALID_CREDENTIALS ) )
{
siResult = eDSPermissionError;
}
else if ( rc == LDAP_NOT_SUPPORTED )
{
siResult = eDSAuthMethodNotSupported;
}
else if ( rc == LDAP_SUCCESS )
{
siResult = eDSNoErr;
}
else
{
siResult = eDSAuthFailed;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( userName != nil )
{
free( userName );
userName = nil;
}
if ( newPasswd != nil )
{
free( newPasswd );
newPasswd = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::DoChangePassword ( sLDAPContextData *inContext, tDataBuffer *inAuthData,
CLDAPv3Configs *inConfigFromXML, CLDAPNode& inLDAPSessionMgr )
{
sInt32 siResult = eDSAuthFailed;
char *pData = nil;
char *name = nil;
uInt32 nameLen = 0;
char *oldPwd = nil;
uInt32 OldPwdLen = 0;
char *newPwd = nil;
uInt32 newPwdLen = 0;
uInt32 offset = 0;
uInt32 buffSize = 0;
uInt32 buffLen = 0;
char *pathStr = nil;
char *accountId = nil;
try
{
if ( inContext == nil ) throw( (sInt32)eDSAuthFailed );
if ( inAuthData == nil ) throw( (sInt32)eDSNullAuthStepData );
pData = inAuthData->fBufferData;
buffSize = inAuthData->fBufferSize;
buffLen = inAuthData->fBufferLength;
if ( buffLen > buffSize ) throw( (sInt32)eDSInvalidBuffFormat );
if ( buffLen < 3 * sizeof( unsigned long ) + 1 ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &nameLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
if (nameLen == 0) throw( (sInt32)eDSInvalidBuffFormat );
if (offset + nameLen > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
name = (char *)::calloc( 1, nameLen + 1 );
::memcpy( name, pData, nameLen );
pData += nameLen;
offset += nameLen;
if (offset + sizeof( unsigned long ) > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &OldPwdLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
if (offset + OldPwdLen > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
oldPwd = (char *)::calloc( 1, OldPwdLen + 1 );
::memcpy( oldPwd, pData, OldPwdLen );
pData += OldPwdLen;
offset += OldPwdLen;
if (offset + sizeof( unsigned long ) > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &newPwdLen, pData, sizeof( unsigned long ) );
pData += sizeof( unsigned long );
offset += sizeof( unsigned long );
if (offset + newPwdLen > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
newPwd = (char *)::calloc( 1, newPwdLen + 1 );
::memcpy( newPwd, pData, newPwdLen );
pData += newPwdLen;
offset += newPwdLen;
if (name)
{
accountId = GetDNForRecordName ( name, inContext, inConfigFromXML, inLDAPSessionMgr );
}
LDAP *aLDAPHost = nil;
siResult = inLDAPSessionMgr.AuthOpen( inContext->fName,
inContext->fHost,
accountId,
oldPwd,
kDSStdAuthClearText,
&aLDAPHost,
&(inContext->fConfigTableIndex),
false);
if( siResult == eDSNoErr ) {
int rc = exop_password_create( aLDAPHost, accountId, newPwd );
if( rc != LDAP_SUCCESS ) {
rc = standard_password_create( aLDAPHost, accountId, newPwd );
}
if ( ( rc == LDAP_INSUFFICIENT_ACCESS ) || ( rc == LDAP_INVALID_CREDENTIALS ) )
{
siResult = eDSPermissionError;
}
else if ( rc == LDAP_NOT_SUPPORTED )
{
siResult = eDSAuthMethodNotSupported;
}
else if ( rc == LDAP_SUCCESS )
{
siResult = eDSNoErr;
}
else
{
siResult = eDSAuthFailed;
}
ldap_unbind(aLDAPHost);
}
else
{
siResult = eDSAuthFailed;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( pathStr != nil )
{
free( pathStr );
pathStr = nil;
}
if ( name != nil )
{
free( name );
name = nil;
}
if ( newPwd != nil )
{
free( newPwd );
newPwd = nil;
}
if ( oldPwd != nil )
{
free( oldPwd );
oldPwd = nil;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::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 if ( ::strcmp( p, kDSStdAuthSetPasswd ) == 0 )
{
*outAuthMethod = kAuthSetPasswd;
}
else if ( ::strcmp( p, kDSStdAuthSetPasswdAsRoot ) == 0 )
{
*outAuthMethod = kAuthSetPasswdAsRoot;
}
else if ( ::strcmp( p, kDSStdAuthChangePasswd ) == 0 )
{
*outAuthMethod = kAuthChangePasswd;
}
else
{
*outAuthMethod = kAuthUnknowMethod;
siResult = eDSAuthMethodNotSupported;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::PWOpenDirNode ( tDirNodeReference fDSRef, char *inNodeName, tDirNodeReference *outNodeRef )
{
sInt32 error = eDSNoErr;
sInt32 error2 = eDSNoErr;
tDataList *pDataList = nil;
pDataList = ::dsBuildFromPathPriv( inNodeName, "/" );
if ( pDataList != nil )
{
error = ::dsOpenDirNode( fDSRef, pDataList, outNodeRef );
error2 = ::dsDataListDeallocatePriv( pDataList );
free( pDataList );
}
return( error );
}
sInt32 CLDAPv3PlugIn::RepackBufferForPWServer ( tDataBufferPtr inBuff, const char *inUserID, unsigned long inUserIDNodeNum, tDataBufferPtr *outBuff )
{
sInt32 result = eDSNoErr;
tDataListPtr dataList = NULL;
tDataNodePtr dataNode = NULL;
unsigned long index, nodeCount;
unsigned long uidLen;
if ( !inBuff || !inUserID || !outBuff )
return eDSAuthParameterError;
try
{
uidLen = strlen(inUserID);
*outBuff = ::dsDataBufferAllocatePriv( inBuff->fBufferLength + uidLen + 1 );
if ( *outBuff == nil ) throw( eMemoryError );
(*outBuff)->fBufferLength = 0;
dataList = dsAuthBufferGetDataListAllocPriv(inBuff);
if ( dataList == nil ) throw( eDSInvalidBuffFormat );
nodeCount = dsDataListGetNodeCountPriv(dataList);
if ( nodeCount < 2 ) throw( eDSInvalidBuffFormat );
for ( index = 1; index <= nodeCount; index++ )
{
if ( index == inUserIDNodeNum )
{
memcpy( (*outBuff)->fBufferData + (*outBuff)->fBufferLength, &uidLen, sizeof(unsigned long) );
(*outBuff)->fBufferLength += sizeof(unsigned long);
memcpy( (*outBuff)->fBufferData + (*outBuff)->fBufferLength, inUserID, uidLen );
(*outBuff)->fBufferLength += uidLen;
}
else
{
result = dsDataListGetNodeAllocPriv(dataList, index, &dataNode);
if ( result != eDSNoErr ) throw( eDSInvalidBuffFormat );
memcpy((*outBuff)->fBufferData + (*outBuff)->fBufferLength, &dataNode->fBufferLength, sizeof(unsigned long));
(*outBuff)->fBufferLength += sizeof(unsigned long);
memcpy( (*outBuff)->fBufferData + (*outBuff)->fBufferLength, dataNode->fBufferData, dataNode->fBufferLength );
(*outBuff)->fBufferLength += dataNode->fBufferLength;
dsDataBufferDeallocatePriv(dataNode);
}
}
(void)dsDataListDeallocatePriv(dataList);
free(dataList);
}
catch( sInt32 error )
{
result = error;
}
return result;
}
sInt32 CLDAPv3PlugIn::GetAuthAuthority ( sLDAPContextData *inContext, tDataBuffer *inAuthData, CLDAPv3Configs *inConfigFromXML, CLDAPNode& inLDAPSessionMgr, unsigned long *outAuthCount, char **outAuthAuthority[] )
{
sInt32 siResult = eDSAuthFailed;
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 *authauthData = nil;
char *pLDAPRecType = nil;
int ldapMsgId = 0;
char *queryFilter = nil;
LDAPMessage *result = nil;
LDAPMessage *entry = nil;
char *attr = nil;
BerElement *ber = nil;
int ldapReturnCode = 0;
int numRecTypes = 1;
bool bResultFound = false;
sLDAPConfigData *pConfig = nil;
char **attrs = nil;
int searchTO = 0;
bool bOCANDGroup = false;
CFArrayRef OCSearchList = nil;
struct berval **berVal = nil;
ber_int_t scope = LDAP_SCOPE_SUBTREE;
try
{
if ( inContext == nil ) throw( (sInt32)eDSBadContextData );
if ( inAuthData == nil ) throw( (sInt32)eDSNullDataBuff );
if ( outAuthAuthority == nil ) throw( (sInt32)eDSNullParameter );
*outAuthCount = 0;
*outAuthAuthority = nil;
pData = inAuthData->fBufferData;
if ( pData == nil ) throw( (sInt32)eDSNullDataBuff );
buffSize = inAuthData->fBufferSize;
buffLen = inAuthData->fBufferLength;
if (buffLen > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
if ( offset + (2 * sizeof( unsigned long ) + 1) > buffLen ) 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 ( offset + nameLen > buffLen ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( userName, pData, nameLen );
pData += nameLen;
offset += nameLen;
if ( offset + sizeof( unsigned long ) > buffLen ) 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 ( offset + pwdLen > buffLen ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( pwd, pData, pwdLen );
attrs = MapAttrToLDAPTypeArray( kDSStdRecordTypeUsers, kDSNAttrAuthenticationAuthority, inContext->fConfigTableIndex, inConfigFromXML );
if ( attrs == nil ) throw( (sInt32)eDSInvalidAttributeType );
CShared::LogIt( 0x0F, "LDAP PlugIn: Attempting to get Authentication Authority" );
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
numRecTypes = 1;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, inConfigFromXML );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while ( (pLDAPRecType != nil) && (!bResultFound) )
{
queryFilter = BuildLDAPQueryFilter( (char *)kDSNAttrRecordName,
userName,
eDSExact,
inContext->fConfigTableIndex,
false,
(char *)kDSStdRecordTypeUsers,
pLDAPRecType,
bOCANDGroup,
OCSearchList,
inConfigFromXML );
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
int numRetries = 2;
while (true)
{
sInt32 searchResult = eDSNoErr;
searchResult = DSSearchLDAP( inLDAPSessionMgr,
inContext,
pLDAPRecType,
scope,
queryFilter,
attrs,
ldapMsgId,
ldapReturnCode);
if (searchResult == eDSRecordNotFound)
{
bResultFound = false;
break;
}
else if (searchResult == eDSCannotAccessSession)
{
bResultFound = false;
if (numRetries == 0)
{
throw( (sInt32)eDSCannotAccessSession );
}
else
{
RebindLDAPSession(inContext, inLDAPSessionMgr);
numRetries--;
}
}
else
{
bResultFound = true;
break;
}
}
if ( bResultFound )
{
DSGetSearchLDAPResult ( inLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
true);
}
if (queryFilter != nil)
{
delete (queryFilter);
queryFilter = nil;
}
if (pLDAPRecType != nil)
{
delete (pLDAPRecType);
pLDAPRecType = nil;
}
numRecTypes++;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, inConfigFromXML );
}
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 )
{
int idx;
int numAuthAuthorities = 0;
berVal = ldap_get_values_len( inContext->fHost, entry, attr );
if ( berVal != nil )
{
numAuthAuthorities = ldap_count_values_len( berVal );
if ( numAuthAuthorities > 0 )
{
*outAuthCount = numAuthAuthorities;
*outAuthAuthority = (char **)calloc( numAuthAuthorities+1, sizeof(char *) );
}
for ( idx = 0; idx < numAuthAuthorities; idx++ )
{
authauthData = (char *)malloc( berVal[idx]->bv_len + 1 );
if ( authauthData == nil ) throw ( eMemoryError );
strncpy( authauthData, berVal[idx]->bv_val, berVal[idx]->bv_len );
authauthData[berVal[idx]->bv_len] = '\0';
CShared::LogIt( 0x0F, "authauth found %s\n", authauthData );
*outAuthAuthority[idx] = authauthData;
}
siResult = eDSNoErr;
ldap_value_free_len( berVal );
berVal = nil;
}
ldap_memfree( attr );
attr = nil;
}
if ( ber != nil )
{
ber_free( ber, 0 );
}
}
}
if ( result != nil )
{
ldap_msgfree( result );
result = nil;
}
}
catch ( sInt32 err )
{
CShared::LogIt( 0x0F, "LDAP PlugIn: Crypt authentication error %l", err );
siResult = err;
}
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
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 CLDAPv3PlugIn::ParseAuthAuthority ( const char * inAuthAuthority,
char ** outVersion,
char ** outAuthTag,
char ** outAuthData )
{
char* authAuthority = NULL;
char* current = NULL;
char* tempPtr = NULL;
sInt32 result = eDSAuthFailed;
if ( inAuthAuthority == NULL || outVersion == NULL
|| outAuthTag == NULL || outAuthData == NULL )
{
return eDSAuthFailed;
}
authAuthority = strdup(inAuthAuthority);
if (authAuthority == NULL)
{
return eDSAuthFailed;
}
current = authAuthority;
do {
tempPtr = strsep(¤t, ";");
if (tempPtr == NULL) break;
*outVersion = strdup(tempPtr);
tempPtr = strsep(¤t, ";");
if (tempPtr == NULL) break;
*outAuthTag = strdup(tempPtr);
tempPtr = strsep(¤t, ";");
if (tempPtr == NULL) break;
*outAuthData = strdup(tempPtr);
result = eDSNoErr;
} while (false);
free(authAuthority);
authAuthority = NULL;
return result;
}
sInt32 CLDAPv3PlugIn::DoUnixCryptAuth ( sLDAPContextData *inContext, tDataBuffer *inAuthData, CLDAPv3Configs *inConfigFromXML, CLDAPNode& inLDAPSessionMgr )
{
sInt32 siResult = eDSAuthFailed;
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;
bool bOCANDGroup = false;
CFArrayRef OCSearchList = nil;
ber_int_t scope = LDAP_SCOPE_SUBTREE;
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 ( offset + (2 * sizeof( unsigned long ) + 1) > buffLen ) 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 ( offset + nameLen > buffLen ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( userName, pData, nameLen );
pData += nameLen;
offset += nameLen;
if ( offset + sizeof( unsigned long ) > buffLen ) 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 ( offset + pwdLen > buffLen ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( pwd, pData, pwdLen );
attrs = MapAttrToLDAPTypeArray( kDSStdRecordTypeUsers, kDS1AttrPassword, inContext->fConfigTableIndex, inConfigFromXML );
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;
}
}
numRecTypes = 1;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, inConfigFromXML );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while ( (pLDAPRecType != nil) && (!bResultFound) )
{
queryFilter = BuildLDAPQueryFilter( (char *)kDSNAttrRecordName,
userName,
eDSExact,
inContext->fConfigTableIndex,
false,
(char *)kDSStdRecordTypeUsers,
pLDAPRecType,
bOCANDGroup,
OCSearchList,
inConfigFromXML );
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
int numRetries = 2;
while (true)
{
sInt32 searchResult = eDSNoErr;
searchResult = DSSearchLDAP( inLDAPSessionMgr,
inContext,
pLDAPRecType,
scope,
queryFilter,
attrs,
ldapMsgId,
ldapReturnCode);
if (searchResult == eDSRecordNotFound)
{
bResultFound = false;
break;
}
else if (searchResult == eDSCannotAccessSession)
{
bResultFound = false;
if (numRetries == 0)
{
throw( (sInt32)eDSCannotAccessSession );
}
else
{
RebindLDAPSession(inContext, inLDAPSessionMgr);
numRetries--;
}
}
else
{
bResultFound = true;
break;
}
}
if ( bResultFound )
{
DSGetSearchLDAPResult ( inLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
true);
}
if (queryFilter != nil)
{
delete (queryFilter);
queryFilter = nil;
}
if (pLDAPRecType != nil)
{
delete (pLDAPRecType);
pLDAPRecType = nil;
}
numRecTypes++;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, inConfigFromXML );
}
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 );
}
}
}
if ( result != nil )
{
ldap_msgfree( result );
result = nil;
}
}
catch ( sInt32 err )
{
CShared::LogIt( 0x0F, "LDAP PlugIn: Crypt authentication error %l", err );
siResult = err;
}
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
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 CLDAPv3PlugIn::DoClearTextAuth ( sLDAPContextData *inContext, tDataBuffer *inAuthData, bool authCheckOnly, CLDAPv3Configs *inConfigFromXML, CLDAPNode& inLDAPSessionMgr )
{
sInt32 siResult = eDSAuthFailed;
char *pData = nil;
char *userName = nil;
char *accountId = nil;
sInt32 nameLen = 0;
char *pwd = nil;
sInt32 pwdLen = 0;
LDAP *aLDAPHost = nil;
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;
}
CShared::LogIt( 0x0F, "LDAP PlugIn: Attempting Cleartext Authentication" );
if (userName)
{
accountId = GetDNForRecordName ( userName, inContext, inConfigFromXML, inLDAPSessionMgr );
}
if (accountId == nil)
{
throw( (sInt32)eDSAuthFailed );
}
if ((pwd != NULL) && (pwd[0] != '\0') && (nameLen != 0))
{
if (!authCheckOnly)
{
siResult = inLDAPSessionMgr.AuthOpen( inContext->fName,
inContext->fHost,
accountId,
pwd,
kDSStdAuthClearText,
&aLDAPHost,
&(inContext->fConfigTableIndex),
true);
if (siResult == eDSNoErr)
{
if (inContext->fLDAPSessionMutex == nil)
{
inContext->fLDAPSessionMutex = new DSMutexSemaphore();
}
inContext->fLDAPSessionMutex->Wait();
inContext->fHost = aLDAPHost;
if (inContext->fAuthType == nil)
{
inContext->fAuthType = strdup(kDSStdAuthClearText);
}
inContext->authCallActive = true;
if (inContext->fUserName != nil)
{
free(inContext->fUserName);
inContext->fUserName = nil;
}
inContext->fUserName = strdup(accountId);
if (inContext->fAuthCredential != nil)
{
free(inContext->fAuthCredential);
inContext->fAuthCredential = nil;
}
inContext->fAuthCredential = strdup(pwd);
inContext->fLDAPSessionMutex->Signal();
}
else
{
siResult = eDSAuthFailed;
}
}
else {
siResult = inLDAPSessionMgr.SimpleAuth( inContext->fName,
accountId,
pwd );
}
}
}
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* CLDAPv3PlugIn::GetDNForRecordName ( char* inRecName, sLDAPContextData *inContext, CLDAPv3Configs *inConfigFromXML, CLDAPNode& inLDAPSessionMgr )
{
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;
bool bOCANDGroup = false;
CFArrayRef OCSearchList = nil;
ber_int_t scope = LDAP_SCOPE_SUBTREE;
try
{
if ( inRecName == nil ) throw( (sInt32)eDSNullRecName );
if ( inContext == nil ) throw( (sInt32)eDSBadContextData );
if (( inContext->fConfigTableIndex < gConfigTableLen) && ( inContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
numRecTypes = 1;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, inConfigFromXML );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while ( (pLDAPRecType != nil) && (!bResultFound) )
{
queryFilter = BuildLDAPQueryFilter( (char *)kDSNAttrRecordName,
inRecName,
eDSExact,
inContext->fConfigTableIndex,
false,
(char *)kDSStdRecordTypeUsers,
pLDAPRecType,
bOCANDGroup,
OCSearchList,
inConfigFromXML );
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
int numRetries = 2;
while (true)
{
sInt32 searchResult = eDSNoErr;
searchResult = DSSearchLDAP( inLDAPSessionMgr,
inContext,
pLDAPRecType,
scope,
queryFilter,
NULL,
ldapMsgId,
ldapReturnCode);
if (searchResult == eDSRecordNotFound)
{
bResultFound = false;
break;
}
else if (searchResult == eDSCannotAccessSession)
{
bResultFound = false;
if (numRetries == 0)
{
throw( (sInt32)eDSCannotAccessSession );
}
else
{
RebindLDAPSession(inContext, inLDAPSessionMgr);
numRetries--;
}
}
else
{
bResultFound = true;
break;
}
}
if ( bResultFound )
{
DSGetSearchLDAPResult ( inLDAPSessionMgr,
inContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
true);
}
if (queryFilter != nil)
{
delete (queryFilter);
queryFilter = nil;
}
if (pLDAPRecType != nil)
{
delete (pLDAPRecType);
pLDAPRecType = nil;
}
numRecTypes++;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( (char *)kDSStdRecordTypeUsers, inContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, inConfigFromXML );
}
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 (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
if ( pLDAPRecType != nil )
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
return( ldapDN );
}
sInt32 CLDAPv3PlugIn::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;
tDataListPtr dataList = NULL;
char* userName = NULL;
char* password = NULL;
char* xmlString = 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 *)gLDAPContextTable->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSBadContextData );
if ( strcmp(pContext->fName,"LDAPv3 Configure") == 0 )
{
aRequest = inData->fInRequestCode;
bufLen = inData->fInRequestData->fBufferLength;
if ( aRequest != 55 )
{
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 55:
dataList = dsAuthBufferGetDataListAllocPriv(inData->fInRequestData);
if ( dataList == nil ) throw( (sInt32)eDSInvalidBuffFormat );
if ( dsDataListGetNodeCountPriv(dataList) != 3 ) throw( (sInt32)eDSInvalidBuffFormat );
userName = dsDataListGetNodeStringPriv(dataList, 1);
if ( userName == nil ) throw( (sInt32)eDSInvalidBuffFormat );
if ( strlen(userName) < 1 ) throw( (sInt32)eDSInvalidBuffFormat );
password = dsDataListGetNodeStringPriv(dataList, 2);
if ( password == nil ) throw( (sInt32)eDSInvalidBuffFormat );
xmlString = dsDataListGetNodeStringPriv(dataList, 3);
if ( xmlString == nil ) throw( (sInt32)eDSInvalidBuffFormat );
xmlData = CFDataCreate(NULL,(UInt8*)xmlString,strlen(xmlString));
siResult = pConfigFromXML->WriteServerMappings( userName, password, xmlData );
break;
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)
{
pConfigFromXML->XMLConfigLock();
xmlData = pConfigFromXML->GetXMLConfig();
if (xmlData != 0)
{
CFRetain(xmlData);
*(CFIndex*)(inData->fOutRequestResponse->fBufferData) = CFDataGetLength(xmlData);
inData->fOutRequestResponse->fBufferLength = sizeof( CFIndex );
CFRelease(xmlData);
xmlData = 0;
}
pConfigFromXML->XMLConfigUnlock();
}
break;
case 77:
CFRange aRange;
if ( inData->fOutRequestResponse == nil ) throw( (sInt32)eDSNullDataBuff );
if ( inData->fOutRequestResponse->fBufferData == nil ) throw( (sInt32)eDSEmptyBuffer );
if (pConfigFromXML)
{
pConfigFromXML->XMLConfigLock();
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;
}
pConfigFromXML->XMLConfigUnlock();
}
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)
{
pConfigFromXML->XMLConfigLock();
siResult = pConfigFromXML->SetXMLConfig(xmlData);
siResult = pConfigFromXML->WriteXMLConfig();
pConfigFromXML->XMLConfigUnlock();
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 CLDAPv3PlugIn::ContextDeallocProc ( void* inContextData )
{
sLDAPContextData *pContext = (sLDAPContextData *) inContextData;
if ( pContext != nil )
{
CleanContextData( pContext );
free( pContext );
pContext = nil;
}
}
void CLDAPv3PlugIn::ContinueDeallocProc ( void* inContinueData )
{
sLDAPContinueData *pLDAPContinue = (sLDAPContinueData *)inContinueData;
if ( pLDAPContinue != nil )
{
if (pLDAPContinue->pResult != nil)
{
ldap_msgfree( pLDAPContinue->pResult );
pLDAPContinue->pResult = nil;
}
free( pLDAPContinue );
pLDAPContinue = nil;
}
}
sInt32 CLDAPv3PlugIn:: RebindLDAPSession ( sLDAPContextData *inContext, CLDAPNode& inLDAPSessionMgr )
{
sInt32 siResult = eDSNoErr;
LDAP *aLDAPHost = nil;
if (inContext != nil)
{
if (inContext->authCallActive)
{
siResult = inLDAPSessionMgr.RebindAuthSession( inContext->fName,
inContext->fHost,
inContext->fUserName,
inContext->fAuthCredential,
inContext->fAuthType,
inContext->fConfigTableIndex,
&aLDAPHost );
}
else
{
siResult = inLDAPSessionMgr.RebindSession( inContext->fName,
inContext->fHost,
&aLDAPHost );
}
inContext->fHost = aLDAPHost;
}
else
{
siResult = eDSNullParameter;
}
return (siResult);
}
sInt32 CLDAPv3PlugIn::GetRecRefLDAPMessage ( sLDAPContextData *inRecContext, LDAPMessage **outResultMsg )
{
sInt32 siResult = eDSNoErr;
sLDAPConfigData *pConfig = nil;
int searchTO = 0;
int numRecTypes = 1;
char *pLDAPRecType = nil;
bool bResultFound = false;
char *queryFilter = nil;
int ldapMsgId = 0;
LDAPMessage *result = nil;
int ldapReturnCode = 0;
bool bOCANDGroup = false;
CFArrayRef OCSearchList = nil;
ber_int_t scope = LDAP_SCOPE_SUBTREE;
try
{
if ( inRecContext->fOpenRecordName == nil ) throw( (sInt32)eDSNullRecName );
if ( inRecContext->fOpenRecordType == nil ) throw( (sInt32)eDSNullRecType );
if (( inRecContext->fConfigTableIndex < gConfigTableLen) && ( inRecContext->fConfigTableIndex >= 1 ))
{
pConfig = (sLDAPConfigData *)gConfigTable->GetItemData( inRecContext->fConfigTableIndex );
if (pConfig != nil)
{
searchTO = pConfig->fSearchTimeout;
}
}
numRecTypes = 1;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( inRecContext->fOpenRecordType, inRecContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, pConfigFromXML );
if ( pLDAPRecType == nil ) throw( (sInt32)eDSInvalidRecordType );
while ( (pLDAPRecType != nil) && (!bResultFound) )
{
queryFilter = BuildLDAPQueryFilter( (char *)kDSNAttrRecordName, inRecContext->fOpenRecordName,
eDSExact,
inRecContext->fConfigTableIndex,
false,
inRecContext->fOpenRecordType,
pLDAPRecType,
bOCANDGroup,
OCSearchList,
pConfigFromXML );
if ( queryFilter == nil ) throw( (sInt32)eDSNullParameter );
int numRetries = 2;
while (true)
{
sInt32 searchResult = eDSNoErr;
searchResult = DSSearchLDAP( fLDAPSessionMgr,
inRecContext,
pLDAPRecType,
scope,
queryFilter,
NULL,
ldapMsgId,
ldapReturnCode);
if (searchResult == eDSRecordNotFound)
{
bResultFound = false;
break;
}
else if (searchResult == eDSCannotAccessSession)
{
bResultFound = false;
if (numRetries == 0)
{
throw( (sInt32)eDSCannotAccessSession );
}
else
{
RebindLDAPSession(inRecContext, fLDAPSessionMgr);
numRetries--;
}
}
else
{
bResultFound = true;
break;
}
}
if ( bResultFound )
{
DSGetSearchLDAPResult ( fLDAPSessionMgr,
inRecContext,
searchTO,
result,
LDAP_MSG_ONE,
ldapMsgId,
ldapReturnCode,
true);
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
if (pLDAPRecType != nil)
{
delete (pLDAPRecType);
pLDAPRecType = nil;
}
numRecTypes++;
bOCANDGroup = false;
if (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
pLDAPRecType = MapRecToLDAPType( inRecContext->fOpenRecordType, inRecContext->fConfigTableIndex, numRecTypes, &bOCANDGroup, &OCSearchList, &scope, pConfigFromXML );
}
if ( (bResultFound) &&
( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) )
{
siResult = eDSNoErr;
} 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 (OCSearchList != nil)
{
CFRelease(OCSearchList);
OCSearchList = nil;
}
if ( pLDAPRecType != nil )
{
delete( pLDAPRecType );
pLDAPRecType = nil;
}
if ( queryFilter != nil )
{
delete( queryFilter );
queryFilter = nil;
}
if (result != nil)
{
*outResultMsg = result;
}
return( siResult );
}
sInt32 CLDAPv3PlugIn::GetUserNameFromAuthBuffer ( tDataBufferPtr inAuthData, unsigned long inUserNameIndex, char **outUserName )
{
tDataListPtr dataList = dsAuthBufferGetDataListAllocPriv(inAuthData);
if (dataList != NULL)
{
*outUserName = dsDataListGetNodeStringPriv(dataList, inUserNameIndex);
dsDataListDeallocatePriv(dataList);
free(dataList);
dataList = NULL;
return eDSNoErr;
}
return eDSInvalidBuffFormat;
}
AuthAuthorityHandlerProc CLDAPv3PlugIn::GetAuthAuthorityHandler ( const char* inTag )
{
if (inTag == NULL)
{
return NULL;
}
for (unsigned int i = 0; i < kAuthAuthorityHandlerProcs; ++i)
{
if (strcasecmp(inTag,sAuthAuthorityHandlerProcs[i].fTag) == 0)
{
return sAuthAuthorityHandlerProcs[i].fHandler;
}
}
return NULL;
}