#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h> //used for mkdir and stat
#include <Security/Authorization.h>
#include "DirServices.h"
#include "DirServicesUtils.h"
#include "DirServicesConst.h"
#include "SharedConsts.h"
#include "CSharedData.h"
#include "PrivateTypes.h"
#include "DSUtils.h"
#include "CAttributeList.h"
#include "CPlugInRef.h"
#include "CBuff.h"
#include "CDataBuff.h"
#include "CRecTypeList.h"
#include "CSearchNode.h"
#include "ServerModuleLib.h"
#include "DSUtils.h"
#include "PluginData.h"
#include "DSCThread.h"
#include "DSEventSemaphore.h"
#include "CAliases.h"
#include "CContinue.h"
static CPlugInRef *gSNNodeRef = nil;
static CContinue *gSNContinue = nil;
static DSEventSemaphore *gKickSearchRequests = nil;
static CSearchNode *gSearchNode = nil;
static const FourCharCode kSearchNodeInfo = 'SnIn';
static const uInt32 kBuffPad = 16;
extern "C" {
CFUUIDRef ModuleFactoryUUID = CFUUIDGetConstantUUIDWithBytes ( NULL, \
0x96, 0xE1, 0xAB, 0xD6, 0xAE, 0xA6, 0x12, 0x26, \
0xA6, 0x10, 0x00, 0x05, 0x02, 0xC1, 0xC7, 0x36 );
}
static CDSServerModule* _Creator ( void )
{
return( new CSearchNode );
}
CDSServerModule::tCreator CDSServerModule::sCreator = _Creator;
static void DoSNPINetworkChange(CFRunLoopTimerRef timer, void *info);
void DoSNPINetworkChange(CFRunLoopTimerRef timer, void *info)
{
if ( info != nil )
{
((CSearchNode *)info)->ReDiscoverNetwork();
}
}
CFStringRef NetworkChangeSNPICopyStringCallback( const void *item );
CFStringRef NetworkChangeSNPICopyStringCallback( const void *item )
{
return CFSTR("NetworkChangeinSNPI");
}
CSearchNode::CSearchNode ( void )
{
fDirRef = 0;
fState = kUnknownState;
fToken = 0;
pSearchConfigList = nil;
fServerRunLoop = nil;
fTransitionCheckTime = 0;
if ( gSNNodeRef == nil )
{
gSNNodeRef = new CPlugInRef( CSearchNode::ContextDeallocProc );
}
if ( gSNContinue == nil )
{
gSNContinue = new CContinue( CSearchNode::ContinueDeallocProc );
}
if ( gKickSearchRequests == nil )
{
gKickSearchRequests = new DSEventSemaphore();
}
gSearchNode = this;
::dsOpenDirService( &fDirRef );
}
CSearchNode::~CSearchNode ( void )
{
sSearchConfig *pConfig = nil;
sSearchConfig *pDeleteConfig = nil;
pConfig = pSearchConfigList;
while (pConfig != nil)
{
pDeleteConfig = pConfig;
pConfig = pConfig->fNext; CleanSearchConfigData( pDeleteConfig );
free( pDeleteConfig );
pDeleteConfig = nil;
}
pSearchConfigList = nil;
if (fDirRef != 0)
{
::dsCloseDirService( fDirRef );
}
}
sInt32 CSearchNode::Validate ( const char *inVersionStr, const uInt32 inSignature )
{
fToken = inSignature;
return( eDSNoErr );
}
sInt32 CSearchNode::PeriodicTask ( void )
{
return( eDSNoErr );
}
sInt32 CSearchNode::Initialize ( void )
{
sInt32 siResult = eDSNoErr;
sInt32 result = eDSNoErr;
sInt32 addLDAPResult = eSearchPathNotDefined;
tDataList *aNodeName = nil;
sSearchConfig *aSearchConfig = nil;
sSearchConfig *lastSearchConfig = nil;
uInt32 index = 0;
uInt32 aSearchConfigType = 0;
char *aSearchNodeName = nil;
char *aSearchConfigFilePrefix = nil;
sSearchList *aSearchNodeList = nil;
sSearchList *autoSearchNodeList = nil;
CConfigs *aConfigFromXML = nil;
uInt32 aSearchPolicy = 0;
eDirNodeType aDirNodeType = kUnknownNodeType;
try
{
siResult = ::dsVerifyDirRefNum(fDirRef);
if (siResult != eDSNoErr)
{
siResult = ::dsOpenDirService( &fDirRef );
if ( siResult != eDSNoErr ) throw( siResult );
}
for (index=0; index<2; index++)
{
if (index == 0)
{
CShared::LogIt( 0x0F, "Setting Authentication Search Node Configuraton" );
aSearchConfigType = eDSAuthenticationSearchNodeName;
aDirNodeType = kSearchNodeType;
}
else if (index == 1)
{
CShared::LogIt( 0x0F, "Setting Contacts Search Node Configuraton" );
aSearchConfigType = eDSContactsSearchNodeName;
aDirNodeType = kContactsSearchNodeType;
}
fMutex.Wait();
aSearchConfig = FindSearchConfigWithKey(aSearchConfigType);
if (aSearchConfig != nil) {
aConfigFromXML = aSearchConfig->pConfigFromXML;
aSearchNodeName = aSearchConfig->fSearchNodeName;
aSearchConfigFilePrefix = aSearchConfig->fSearchConfigFilePrefix;
}
else
{
if (index == 0)
{
aSearchNodeName = (char *) ::calloc(sizeof(kstrAuthenticationNodeName) + 1, sizeof(char));
::strcpy(aSearchNodeName, kstrAuthenticationNodeName);
aSearchConfigFilePrefix = (char *) ::calloc(sizeof(kstrAuthenticationConfigFilePrefix) + 1, sizeof(char));
::strcpy(aSearchConfigFilePrefix, kstrAuthenticationConfigFilePrefix);
}
else
{
aSearchNodeName = (char *) ::calloc(sizeof(kstrContactsNodeName) + 1, sizeof(char));
::strcpy(aSearchNodeName, kstrContactsNodeName);
aSearchConfigFilePrefix = (char *) ::calloc(sizeof(kstrContactsConfigFilePrefix) + 1, sizeof(char));
::strcpy(aSearchConfigFilePrefix, kstrContactsConfigFilePrefix);
}
}
fMutex.Signal();
if ( aConfigFromXML == nil )
{
aConfigFromXML = new CConfigs();
if ( aConfigFromXML != nil )
{
result = aConfigFromXML->Init( aSearchConfigFilePrefix, aSearchPolicy );
if ( result != eDSNoErr ) {
aSearchPolicy = 1; }
}
else
{
aSearchPolicy = 1; }
}
else if (aSearchConfig != nil) {
aSearchPolicy = aSearchConfig->fSearchPolicy;
}
switch ( aSearchPolicy )
{
case kCustomSearchPolicy:
CShared::LogIt( 0x0F, "Setting search policy to Custom search" );
aSearchNodeList = aConfigFromXML->GetCustom();
siResult = AddLocalNodesAsFirstPaths(&aSearchNodeList);
break;
case kLocalSearchPolicy:
CShared::LogIt( 0x0F, "Setting search policy to Local search" );
siResult = AddLocalNodesAsFirstPaths(&aSearchNodeList);
break;
case kNetInfoSearchPolicy:
default:
CShared::LogIt( 0x0F, "Setting search policy to NetInfo default" );
if (autoSearchNodeList == nil)
{
siResult = DoNetInfoDefault(&aSearchNodeList);
autoSearchNodeList = DupSearchListWithNewRefs(aSearchNodeList);
}
else
{
aSearchNodeList = DupSearchListWithNewRefs(autoSearchNodeList);
}
break;
}
if (siResult == eDSNoErr)
{
if (aSearchPolicy == kNetInfoSearchPolicy)
{
if ( aConfigFromXML->IsDHCPLDAPEnabled() )
{
addLDAPResult = AddDefaultLDAPNodesLast(&aSearchNodeList);
}
}
if (aSearchConfig != nil) {
CleanSearchListData( aSearchConfig->fSearchNodeList );
aSearchConfig->fSearchNodeList = aSearchNodeList;
aSearchConfig->fSearchPolicy = aSearchPolicy;
}
else
{
aSearchConfig = MakeSearchConfigData( aSearchNodeList,
aSearchPolicy,
aConfigFromXML,
aSearchNodeName,
aSearchConfigFilePrefix,
aDirNodeType,
aSearchConfigType);
AddSearchConfigToList(aSearchConfig);
}
if (addLDAPResult == eSearchPathNotDefined)
{
SetSearchPolicyIndicatorFile(aSearchConfigType, aSearchPolicy);
}
else {
SetSearchPolicyIndicatorFile(aSearchConfigType, kCustomSearchPolicy);
}
addLDAPResult = eSearchPathNotDefined;
aSearchNodeList = nil;
aSearchPolicy = 0;
aConfigFromXML = nil;
aSearchNodeName = nil;
aSearchConfigFilePrefix = nil;
lastSearchConfig = aSearchConfig;
aSearchConfig = nil;
fState = kUnknownState;
fState += kInitalized;
fState += kActive;
CSearchNode::WakeUpRequests();
}
}
if ( (autoSearchNodeList != nil) && (lastSearchConfig != nil) )
{
CleanSearchListData( autoSearchNodeList );
}
{ CShared::LogIt( 0x0F, "Setting Detault Network Search Node Configuraton" );
aSearchConfigType = eDSNetworkSearchNodeName;
aDirNodeType = kNetworkSearchNodeType;
aSearchPolicy = kCustomSearchPolicy;
fMutex.Wait();
aSearchConfig = FindSearchConfigWithKey(aSearchConfigType);
if (aSearchConfig != nil) {
aConfigFromXML = aSearchConfig->pConfigFromXML;
aSearchNodeName = aSearchConfig->fSearchNodeName;
aSearchConfigFilePrefix = aSearchConfig->fSearchConfigFilePrefix; }
else
{
aSearchNodeName = (char *) ::calloc( 1, sizeof(kstrNetworkNodeName) + 1 );
::strcpy(aSearchNodeName, kstrNetworkNodeName);
aSearchConfigFilePrefix = NULL;
if ( aConfigFromXML == nil )
{
aConfigFromXML = new CConfigs();
}
}
fMutex.Signal();
if (aSearchConfig != nil) {
CleanSearchListData( aSearchConfig->fSearchNodeList );
aSearchConfig->fSearchNodeList = aSearchNodeList;
aSearchConfig->fSearchPolicy = aSearchPolicy;
}
else
{
aSearchConfig = MakeSearchConfigData( aSearchNodeList,
aSearchPolicy,
aConfigFromXML,
aSearchNodeName,
aSearchConfigFilePrefix,
aDirNodeType,
aSearchConfigType);
AddSearchConfigToList(aSearchConfig);
}
}
}
catch( sInt32 err )
{
siResult = err;
fState = kUnknownState;
fState += kFailedToInit;
}
fMutex.Wait();
aSearchConfig = pSearchConfigList;
while (aSearchConfig != nil) {
aNodeName = ::dsBuildFromPathPriv( aSearchConfig->fSearchNodeName, "/" );
if ( aNodeName != nil )
{
DSRegisterNode( fToken, aNodeName, aSearchConfig->fDirNodeType );
::dsDataListDeallocatePriv( aNodeName );
free( aNodeName );
aNodeName = nil;
}
aSearchConfig = aSearchConfig->fNext;
}
fMutex.Signal();
return( siResult );
}
sInt32 CSearchNode:: SwitchSearchPolicy ( uInt32 inSearchPolicy, sSearchConfig *inSearchConfig )
{
sInt32 siResult = eDSNoErr;
sInt32 addLDAPResult = eSearchPathNotDefined;
fMutex.Wait();
try
{
if ( inSearchConfig->pConfigFromXML == nil )
{
inSearchConfig->pConfigFromXML = new CConfigs();
if ( inSearchConfig->pConfigFromXML == nil ) throw( (sInt32)eDSPlugInConfigFileError );
siResult = inSearchConfig->pConfigFromXML->Init( inSearchConfig->fSearchConfigFilePrefix, inSearchConfig->fSearchPolicy );
if ( siResult != eDSNoErr ) throw( siResult );
}
inSearchConfig->fSearchPolicy = inSearchPolicy;
CleanSearchListData( inSearchConfig->fSearchNodeList );
inSearchConfig->fSearchNodeList = nil;
switch ( inSearchConfig->fSearchPolicy )
{
case kCustomSearchPolicy:
CShared::LogIt( 0x0F, "Setting search policy to Custom search" );
inSearchConfig->fSearchNodeList = inSearchConfig->pConfigFromXML->GetCustom();
siResult = AddLocalNodesAsFirstPaths(&(inSearchConfig->fSearchNodeList));
break;
case kLocalSearchPolicy:
CShared::LogIt( 0x0F, "Setting search policy to Local search" );
siResult = AddLocalNodesAsFirstPaths(&(inSearchConfig->fSearchNodeList));
break;
case kNetInfoSearchPolicy:
default:
CShared::LogIt( 0x0F, "Setting search policy to NetInfo default" );
siResult = DoNetInfoDefault(&(inSearchConfig->fSearchNodeList));
break;
}
if (siResult == eDSNoErr)
{
if (inSearchConfig->fSearchPolicy == kNetInfoSearchPolicy)
{
if ( inSearchConfig->pConfigFromXML == nil
|| inSearchConfig->pConfigFromXML->IsDHCPLDAPEnabled() )
{
addLDAPResult = AddDefaultLDAPNodesLast(&(inSearchConfig->fSearchNodeList));
}
}
fState = kUnknownState;
fState += kInitalized;
fState += kActive;
if (addLDAPResult == eSearchPathNotDefined)
{
SetSearchPolicyIndicatorFile( inSearchConfig->fSearchConfigKey, inSearchConfig->fSearchPolicy );
}
else {
SetSearchPolicyIndicatorFile( inSearchConfig->fSearchConfigKey, kCustomSearchPolicy );
}
gSNNodeRef->DoOnAllItems(CSearchNode::ContextSetListChangedProc);
CSearchNode::WakeUpRequests();
}
}
catch( sInt32 err )
{
siResult = err;
fState = kUnknownState;
fState += kInactive;
}
fMutex.Signal();
return( siResult );
}
sInt32 CSearchNode::DoNetInfoDefault ( sSearchList **inSearchNodeList )
{
sInt32 siResult = eDSNoErr;
*inSearchNodeList = GetNetInfoPaths(false,nil);
if ( *inSearchNodeList == nil )
{
siResult = eSearchPathNotDefined;
}
return( siResult );
}
sSearchList *CSearchNode:: GetNetInfoPaths ( bool bFullPath, char** localNodeName )
{
sInt32 siResult = eDSNoErr;
bool bLocalIsRoot = false;
char *p = nil;
char *n = nil;
tDataBuffer *pNodeNameBuff = nil;
tDataBuffer *pLocalNodeBuff = nil;
tDataList *pNodeNameDL = nil;
tDataList *pNodePath = nil;
uInt32 uiCount = 0;
sSearchList *pCurList = nil;
sSearchList *pSrchList = nil;
uInt32 uiCntr = 1;
sSearchList *outSrchList = nil;
char *aSearchPath = nil;
tDirNodeReference aNodeRef = 0;
tAttributeListRef attrListRef = 0;
tAttributeValueListRef attrValueListRef = 0;
tAttributeValueEntry *pAttrValueEntry = nil;
tAttributeEntry *pAttrEntry = nil;
uInt32 aIndex = 0;
uInt32 aSearchPathLen = 0;
bool bSetLocalFirst = true;
tContextData context = NULL;
try
{
if (localNodeName == nil || *localNodeName == nil)
{
pLocalNodeBuff = ::dsDataBufferAllocate( fDirRef, 512 );
if ( pLocalNodeBuff == nil ) throw( (sInt32)eMemoryError );
do
{
siResult = dsFindDirNodes( fDirRef, pLocalNodeBuff, NULL, eDSLocalNodeNames, &uiCount, &context );
if (siResult == eDSBufferTooSmall)
{
uInt32 bufSize = pLocalNodeBuff->fBufferSize;
dsDataBufferDeallocatePriv( pLocalNodeBuff );
pLocalNodeBuff = nil;
pLocalNodeBuff = ::dsDataBufferAllocatePriv( bufSize * 2 );
}
} while (siResult == eDSBufferTooSmall);
if ( siResult != eDSNoErr ) throw( siResult );
if ( uiCount == 0 )
{
CShared::LogIt( 0x0F, "CSearchNode::GetNetInfoPaths:dsFindDirNodes on local returned zero" );
throw( siResult ); }
siResult = dsGetDirNodeName( fDirRef, pLocalNodeBuff, 1, &pNodeNameDL );
if ( siResult != eDSNoErr )
{
CShared::LogIt( 0x0F, "CSearchNode::GetNetInfoPaths:dsGetDirNodeName on local returned error %d", siResult );
throw( siResult );
}
if ( pLocalNodeBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pLocalNodeBuff );
pLocalNodeBuff = nil;
}
siResult = ::dsOpenDirNode( fDirRef, pNodeNameDL, &aNodeRef );
if ( siResult != eDSNoErr )
{
CShared::LogIt( 0x0F, "CSearchNode::GetNetInfoPaths:dsOpenDirNode on local returned error %d" );
throw( siResult );
}
::dsDataListDeAllocate( fDirRef, pNodeNameDL, false );
free(pNodeNameDL);
pNodeNameDL = nil;
pNodePath = ::dsBuildListFromStringsPriv( kDSNAttrNodePath, nil );
if ( pNodePath == nil ) throw( (sInt32)eMemoryAllocError );
pNodeNameBuff = ::dsDataBufferAllocate( fDirRef, 1024 );
if ( pNodeNameBuff == nil ) throw( (sInt32)eMemoryError );
uiCount = 0;
siResult = ::dsGetDirNodeInfo( aNodeRef, pNodePath, pNodeNameBuff, false, &uiCount, &attrListRef, nil );
if ( siResult != eDSNoErr ) throw( siResult );
if ( uiCount == 0 ) throw ( (sInt32)eNoSearchNodesFound );
::dsDataListDeAllocate( fDirRef, pNodePath, false );
free(pNodePath);
pNodePath = nil;
siResult = dsGetAttributeEntry( aNodeRef, pNodeNameBuff, attrListRef, 1, &attrValueListRef, &pAttrEntry );
if ( siResult != eDSNoErr ) throw( siResult );
for (aIndex=1; aIndex < (pAttrEntry->fAttributeValueCount+1); aIndex++)
{
siResult = dsGetAttributeValue( aNodeRef, pNodeNameBuff, aIndex, attrValueListRef, &pAttrValueEntry );
if ( siResult != eDSNoErr ) throw( siResult );
if ( pAttrValueEntry->fAttributeValueData.fBufferData == nil ) throw( (sInt32)eMemoryAllocError );
aSearchPathLen += (::strlen(pAttrValueEntry->fAttributeValueData.fBufferData) + 1); dsDeallocAttributeValueEntry(fDirRef, pAttrValueEntry);
pAttrValueEntry = nil;
}
aSearchPath = (char *) ::calloc( 1, aSearchPathLen + 1);
for (aIndex=1; aIndex < (pAttrEntry->fAttributeValueCount+1); aIndex++)
{
siResult = dsGetAttributeValue( aNodeRef, pNodeNameBuff, aIndex, attrValueListRef, &pAttrValueEntry );
if ( siResult != eDSNoErr ) throw( siResult );
if ( pAttrValueEntry->fAttributeValueData.fBufferData == nil ) throw( (sInt32)eMemoryAllocError );
::strcat(aSearchPath, "/");
::strcat(aSearchPath, pAttrValueEntry->fAttributeValueData.fBufferData);
dsDeallocAttributeValueEntry(fDirRef, pAttrValueEntry);
pAttrValueEntry = nil;
}
dsCloseAttributeList(attrListRef);
dsCloseAttributeValueList(attrValueListRef);
dsDeallocAttributeEntry(fDirRef, pAttrEntry);
pAttrEntry = nil;
siResult = ::dsCloseDirNode(aNodeRef);
if ( siResult != eDSNoErr ) throw( siResult );
if (localNodeName != nil)
{
*localNodeName = strdup(aSearchPath);
}
}
else if (localNodeName != nil)
{
aSearchPath = strdup(*localNodeName);
}
if ( ::strcmp( "/NetInfo/root", aSearchPath ) == 0 )
{
bLocalIsRoot = true;
}
if ( ::strncmp( "/NetInfo/root", aSearchPath, 13 ) == 0 )
{
p = aSearchPath;
n = p + ::strlen( aSearchPath );
do
{
pSrchList = (sSearchList *)::calloc( sizeof( sSearchList ), sizeof(char) );
if (bSetLocalFirst) {
if (bFullPath)
{
pSrchList->fNodeName = (char *)::calloc( ::strlen( p ) + 1, sizeof(char) );
::strcpy( pSrchList->fNodeName, p );
}
else
{
pSrchList->fNodeName = (char *)::calloc( ::strlen( kstrDefaultLocalNodeName ) + 1, sizeof(char) );
::strcpy( pSrchList->fNodeName, kstrDefaultLocalNodeName );
}
}
else
{
pSrchList->fNodeName = (char *)::calloc( ::strlen( p ) + 1, sizeof(char) );
::strcpy( pSrchList->fNodeName, p );
}
if (bSetLocalFirst)
{
pSrchList->fDataList = ::dsBuildFromPathPriv( kstrDefaultLocalNodeName, "/" );
CShared::LogIt( 0x0F, "Search policy node %l = %s", uiCntr++, pSrchList->fNodeName );
bSetLocalFirst = false;
}
else
{
pSrchList->fDataList = ::dsBuildFromPathPriv( pSrchList->fNodeName, "/" );
CShared::LogIt( 0x0F, "Search policy node %l = %s", uiCntr++, pSrchList->fNodeName );
}
if ( outSrchList == nil )
{
outSrchList = pSrchList;
pCurList = outSrchList;
}
else
{
pCurList->fNext = pSrchList;
pCurList = pCurList->fNext;
}
if ( ::strcmp( p, "/NetInfo/root" ) != 0 )
{
while ( (n != p) && (*n != '/') )
{
n--;
}
if ( *n == '/' )
{
*n = '\0';
}
}
else
{
n = p;
}
} while ( (p != n) && (bLocalIsRoot == false) );
siResult = eDSNoErr;
}
if ( p != nil )
{
free( p ); aSearchPath = nil;
p = nil; }
if ( pNodeNameBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pNodeNameBuff );
pNodeNameBuff = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( pNodeNameDL != nil )
{
::dsDataListDeAllocate( fDirRef, pNodeNameDL, false );
free(pNodeNameDL);
pNodeNameDL = nil;
}
if ( pNodePath != nil )
{
::dsDataListDeAllocate( fDirRef, pNodePath, false );
free(pNodePath);
pNodePath = nil;
}
if ( pLocalNodeBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pLocalNodeBuff );
pLocalNodeBuff = nil;
}
if ( pNodeNameBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pNodeNameBuff );
pNodeNameBuff = nil;
}
if ( aSearchPath != nil )
{
free( aSearchPath );
aSearchPath = nil;
}
if (outSrchList == nil)
{
outSrchList = (sSearchList *)::calloc( sizeof( sSearchList ), sizeof(char) );
if (outSrchList != nil)
{
outSrchList->fNodeName = strdup(kstrDefaultLocalNodeName);
outSrchList->fDataList = ::dsBuildFromPathPriv( kstrDefaultLocalNodeName, "/" );
outSrchList->fNodeRef = 0;
outSrchList->fOpened = false;
outSrchList->fNext = nil;
CShared::LogIt( 0x0F, "GetNetInfoPaths: Search policy node forced to explicit default local node due to failed init");
}
else
{
CShared::LogIt( 0x0F, "GetNetInfoPaths: Search policy node failed to force to explicit default local node due to failed init");
}
}
return( outSrchList );
}
sInt32 CSearchNode::AddDefaultLDAPNodesLast( sSearchList **inSearchNodeList )
{
sInt32 siResult = eDSNoErr;
sSearchList *ldapSrchList = nil;
sSearchList *pSrchList = nil;
ldapSrchList = GetDefaultLDAPPaths();
if ( ldapSrchList == nil )
{
siResult = eSearchPathNotDefined;
}
else
{
if ( *inSearchNodeList == nil )
{
*inSearchNodeList = ldapSrchList;
}
else
{
pSrchList = *inSearchNodeList;
while(pSrchList->fNext != nil)
{
pSrchList = pSrchList->fNext;
}
pSrchList->fNext = ldapSrchList;
}
}
return( siResult );
}
sInt32 CSearchNode::AddLocalNodesAsFirstPaths( sSearchList **inSearchNodeList )
{
sInt32 siResult = eDSNoErr;
sSearchList *localSrchList = nil;
sSearchList *pSrchList = nil;
char *localNodeName = nil;
localNodeName = strdup( kstrDefaultLocalNodeName );
localSrchList = GetLocalPaths(&localNodeName);
free(localNodeName);
if ( localSrchList == nil )
{
siResult = eSearchPathNotDefined;
}
else
{
if ( *inSearchNodeList == nil )
{
*inSearchNodeList = localSrchList;
}
else
{
pSrchList = localSrchList;
while (pSrchList->fNext != nil)
{
pSrchList = pSrchList->fNext;
}
pSrchList->fNext = *inSearchNodeList;
*inSearchNodeList = localSrchList;
}
}
return( siResult );
}
sSearchList *CSearchNode:: GetLocalPaths ( char** localNodeName )
{
sInt32 siResult = eDSNoErr;
tDataBuffer *pNodeNameBuff = nil;
tDataBuffer *pLocalNodeBuff = nil;
tDataList *pNodeNameDL = nil;
tDataList *pNodePath = nil;
uInt32 uiCount = 0;
sSearchList *pCurList = nil;
sSearchList *pSrchList = nil;
uInt32 uiCntr = 1;
sSearchList *outSrchList = nil;
char *aSearchPath = nil;
tDirNodeReference aNodeRef = 0;
tAttributeListRef attrListRef = 0;
tAttributeValueListRef attrValueListRef = 0;
tAttributeValueEntry *pAttrValueEntry = nil;
tAttributeEntry *pAttrEntry = nil;
uInt32 aIndex = 0;
uInt32 aSearchPathLen = 0;
tContextData context = NULL;
try
{
if (localNodeName == nil || *localNodeName == nil)
{
pLocalNodeBuff = ::dsDataBufferAllocate( fDirRef, 512 );
if ( pLocalNodeBuff == nil ) throw( (sInt32)eMemoryError );
do
{
siResult = dsFindDirNodes( fDirRef, pLocalNodeBuff, NULL, eDSLocalNodeNames, &uiCount, &context );
if (siResult == eDSBufferTooSmall)
{
uInt32 bufSize = pLocalNodeBuff->fBufferSize;
dsDataBufferDeallocatePriv( pLocalNodeBuff );
pLocalNodeBuff = nil;
pLocalNodeBuff = ::dsDataBufferAllocatePriv( bufSize * 2 );
}
} while (siResult == eDSBufferTooSmall);
if ( siResult != eDSNoErr ) throw( siResult );
if ( uiCount == 0 )
{
CShared::LogIt( 0x0F, "CSearchNode::GetLocalPaths:dsFindDirNodes on local returned zero" );
throw( siResult ); }
siResult = dsGetDirNodeName( fDirRef, pLocalNodeBuff, 1, &pNodeNameDL );
if ( siResult != eDSNoErr )
{
CShared::LogIt( 0x0F, "CSearchNode::GetLocalPaths:dsGetDirNodeName on local returned error %d", siResult );
throw( siResult );
}
if ( pLocalNodeBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pLocalNodeBuff );
pLocalNodeBuff = nil;
}
siResult = ::dsOpenDirNode( fDirRef, pNodeNameDL, &aNodeRef );
if ( siResult != eDSNoErr )
{
CShared::LogIt( 0x0F, "CSearchNode::GetLocalPaths:dsOpenDirNode on local returned error %d" );
throw( siResult );
}
::dsDataListDeAllocate( fDirRef, pNodeNameDL, false );
free(pNodeNameDL);
pNodeNameDL = nil;
pNodePath = ::dsBuildListFromStringsPriv( kDSNAttrNodePath, nil );
if ( pNodePath == nil ) throw( (sInt32)eMemoryAllocError );
pNodeNameBuff = ::dsDataBufferAllocate( fDirRef, 1024 );
if ( pNodeNameBuff == nil ) throw( (sInt32)eMemoryError );
uiCount = 0;
siResult = ::dsGetDirNodeInfo( aNodeRef, pNodePath, pNodeNameBuff, false, &uiCount, &attrListRef, nil );
if ( siResult != eDSNoErr ) throw( siResult );
if ( uiCount == 0 ) throw ( (sInt32)eNoSearchNodesFound );
::dsDataListDeAllocate( fDirRef, pNodePath, false );
free(pNodePath);
pNodePath = nil;
siResult = dsGetAttributeEntry( aNodeRef, pNodeNameBuff, attrListRef, 1, &attrValueListRef, &pAttrEntry );
if ( siResult != eDSNoErr ) throw( siResult );
for (aIndex=1; aIndex < (pAttrEntry->fAttributeValueCount+1); aIndex++)
{
siResult = dsGetAttributeValue( aNodeRef, pNodeNameBuff, aIndex, attrValueListRef, &pAttrValueEntry );
if ( siResult != eDSNoErr ) throw( siResult );
if ( pAttrValueEntry->fAttributeValueData.fBufferData == nil ) throw( (sInt32)eMemoryAllocError );
aSearchPathLen += (::strlen(pAttrValueEntry->fAttributeValueData.fBufferData) + 1); dsDeallocAttributeValueEntry(fDirRef, pAttrValueEntry);
pAttrValueEntry = nil;
}
aSearchPath = (char *) ::calloc( 1, aSearchPathLen + 1);
for (aIndex=1; aIndex < (pAttrEntry->fAttributeValueCount+1); aIndex++)
{
siResult = dsGetAttributeValue( aNodeRef, pNodeNameBuff, aIndex, attrValueListRef, &pAttrValueEntry );
if ( siResult != eDSNoErr ) throw( siResult );
if ( pAttrValueEntry->fAttributeValueData.fBufferData == nil ) throw( (sInt32)eMemoryAllocError );
::strcat(aSearchPath, "/");
::strcat(aSearchPath, pAttrValueEntry->fAttributeValueData.fBufferData);
dsDeallocAttributeValueEntry(fDirRef, pAttrValueEntry);
pAttrValueEntry = nil;
}
dsCloseAttributeList(attrListRef);
dsCloseAttributeValueList(attrValueListRef);
dsDeallocAttributeEntry(fDirRef, pAttrEntry);
pAttrEntry = nil;
siResult = ::dsCloseDirNode(aNodeRef);
if ( siResult != eDSNoErr ) throw( siResult );
}
else if (localNodeName != nil && *localNodeName != nil)
{
aSearchPath = *localNodeName;
}
if ( aSearchPath != nil )
{
pSrchList = (sSearchList *)::calloc( sizeof( sSearchList ), sizeof(char) );
pSrchList->fNodeName = strdup( aSearchPath );
if (localNodeName != nil)
{
*localNodeName = aSearchPath;
}
else
{
free(aSearchPath);
}
aSearchPath = nil;
pSrchList->fDataList = ::dsBuildFromPathPriv( kstrDefaultLocalNodeName, "/" );
CShared::LogIt( 0x0F, "Search policy node %l = %s", uiCntr++, pSrchList->fNodeName );
if ( outSrchList == nil )
{
outSrchList = pSrchList;
outSrchList->fNext = nil;
pCurList = outSrchList;
}
else
{
pCurList->fNext = pSrchList;
pCurList = pSrchList;
pCurList->fNext = nil;
}
siResult = eDSNoErr;
}
if ( pNodeNameDL != nil )
{
::dsDataListDeAllocate( fDirRef, pNodeNameDL, false );
free(pNodeNameDL);
pNodeNameDL = nil;
}
if ( pNodeNameBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pNodeNameBuff );
pNodeNameBuff = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( pLocalNodeBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pLocalNodeBuff );
pLocalNodeBuff = nil;
}
if ( pNodeNameBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pNodeNameBuff );
pNodeNameBuff = nil;
}
if ( pNodePath != nil )
{
::dsDataListDeAllocate( fDirRef, pNodePath, false );
free(pNodePath);
pNodePath = nil;
}
if ( aSearchPath != nil )
{
free( aSearchPath );
aSearchPath = nil;
}
if (outSrchList == nil)
{
outSrchList = (sSearchList *)::calloc( sizeof( sSearchList ), sizeof(char) );
if (outSrchList != nil)
{
outSrchList->fNodeName = strdup(kstrDefaultLocalNodeName);
outSrchList->fDataList = ::dsBuildFromPathPriv( kstrDefaultLocalNodeName, "/" );
outSrchList->fNodeRef = 0;
outSrchList->fOpened = false;
outSrchList->fNext = nil;
CShared::LogIt( 0x0F, "GetLocalPaths: Search policy node forced to explicit default local node due to failed init");
}
else
{
CShared::LogIt( 0x0F, "GetLocalPaths: Search policy node failed to force to explicit default local node due to failed init");
}
}
return( outSrchList );
}
sSearchList *CSearchNode:: GetDefaultLDAPPaths ( void )
{
sInt32 siResult = eDSNoErr;
tDataBuffer *pNodeBuff = nil;
tDataList *pNodeNameDL = nil;
tDataList *pNodeList = nil;
uInt32 uiCount = 0;
sSearchList *pCurList = nil;
sSearchList *pSrchList = nil;
uInt32 uiCntr = 1;
sSearchList *outSrchList = nil;
tDirNodeReference aNodeRef = 0;
tAttributeListRef attrListRef = 0;
tAttributeValueListRef attrValueListRef = 0;
tAttributeValueEntry *pAttrValueEntry = nil;
tAttributeEntry *pAttrEntry = nil;
uInt32 aIndex = 0;
try
{
pNodeBuff = ::dsDataBufferAllocate( fDirRef, 2048 );
if ( pNodeBuff == nil ) throw( (sInt32)eMemoryError );
pNodeNameDL = ::dsBuildListFromStringsPriv( "LDAPv3", nil );
if ( pNodeNameDL == nil ) throw( (sInt32)eMemoryAllocError );
siResult = ::dsOpenDirNode( fDirRef, pNodeNameDL, &aNodeRef );
if ( siResult != eDSNoErr ) throw( siResult );
::dsDataListDeAllocate( fDirRef, pNodeNameDL, false );
free(pNodeNameDL);
pNodeNameDL = nil;
pNodeList = ::dsBuildListFromStringsPriv( kDSNAttrDefaultLDAPPaths, nil );
if ( pNodeList == nil ) throw( (sInt32)eMemoryAllocError );
siResult = ::dsGetDirNodeInfo( aNodeRef, pNodeList, pNodeBuff, false, &uiCount, &attrListRef, nil );
if ( siResult != eDSNoErr ) throw( siResult );
if ( uiCount == 0 ) throw ( (sInt32)eNoSearchNodesFound );
::dsDataListDeAllocate( fDirRef, pNodeList, false );
free(pNodeList);
pNodeList = nil;
siResult = dsGetAttributeEntry( aNodeRef, pNodeBuff, attrListRef, 1, &attrValueListRef, &pAttrEntry );
if ( siResult != eDSNoErr ) throw( siResult );
for (aIndex=1; aIndex < (pAttrEntry->fAttributeValueCount+1); aIndex++)
{
siResult = dsGetAttributeValue( aNodeRef, pNodeBuff, aIndex, attrValueListRef, &pAttrValueEntry );
if ( siResult != eDSNoErr ) throw( siResult );
if ( pAttrValueEntry->fAttributeValueData.fBufferData == nil ) throw( (sInt32)eMemoryAllocError );
pSrchList = (sSearchList *)::calloc( sizeof( sSearchList ), sizeof(char) );
pSrchList->fNodeName = (char *)::calloc( pAttrValueEntry->fAttributeValueData.fBufferLength + 1, sizeof(char) );
::strcpy( pSrchList->fNodeName, pAttrValueEntry->fAttributeValueData.fBufferData );
pSrchList->fDataList = ::dsBuildFromPathPriv( pSrchList->fNodeName, "/" );
CShared::LogIt( 0x0F, "Search policy node %l = %s", uiCntr++, pSrchList->fNodeName );
if ( outSrchList == nil )
{
outSrchList = pSrchList;
outSrchList->fNext = nil;
pCurList = outSrchList;
}
else
{
pCurList->fNext = pSrchList;
pCurList = pSrchList;
pCurList->fNext = nil;
}
dsDeallocAttributeValueEntry(fDirRef, pAttrValueEntry);
pAttrValueEntry = nil;
}
dsCloseAttributeList(attrListRef);
dsCloseAttributeValueList(attrValueListRef);
dsDeallocAttributeEntry(fDirRef, pAttrEntry);
pAttrEntry = nil;
siResult = ::dsCloseDirNode(aNodeRef);
if ( siResult != eDSNoErr ) throw( siResult );
if ( pNodeBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pNodeBuff );
pNodeBuff = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( pNodeBuff != nil )
{
::dsDataBufferDeAllocate( fDirRef, pNodeBuff );
pNodeBuff = nil;
}
if ( pNodeList != nil )
{
::dsDataListDeAllocate( fDirRef, pNodeList, false );
free(pNodeList);
pNodeList = nil;
}
if ( pNodeNameDL != nil )
{
::dsDataListDeAllocate( fDirRef, pNodeNameDL, false );
free(pNodeNameDL);
pNodeNameDL = nil;
}
return( outSrchList );
}
void CSearchNode::WakeUpRequests ( void )
{
gKickSearchRequests->Signal();
}
void CSearchNode::WaitForInit ( void )
{
volatile uInt32 uiAttempts = 0;
while ( !(fState & kInitalized) &&
!(fState & kFailedToInit) )
{
if ( uiAttempts++ >= 240 )
{
return;
}
gKickSearchRequests->Wait( (uInt32)(.5 * kMilliSecsPerSec) );
gKickSearchRequests->Reset();
}
}
sInt32 CSearchNode::ProcessRequest ( void *inData )
{
sInt32 siResult = eDSNoErr;
char *pathStr = nil;
try
{
if ( inData == nil )
{
throw( (sInt32)ePlugInDataError );
}
if (((sHeader *)inData)->fType == kOpenDirNode)
{
if (((sOpenDirNode *)inData)->fInDirNodeName != nil)
{
pathStr = ::dsGetPathFromListPriv( ((sOpenDirNode *)inData)->fInDirNodeName, "/" );
if ( (pathStr != nil) && (strncmp(pathStr,"/Search",7) != 0) )
{
throw( (sInt32)eDSOpenNodeFailed);
}
}
}
WaitForInit();
if (fState & kFailedToInit) throw( (sInt32)ePlugInFailedToInitialize );
if ( !(fState & kActive) ) throw( (sInt32)ePlugInNotActive );
if ( ((sHeader *)inData)->fType == kHandleNetworkTransition )
{
HandleMultipleNetworkTransitions();
}
else if ( ((sHeader *)inData)->fType == kServerRunLoop )
{
if ( (((sHeader *)inData)->fContextData) != nil )
{
fServerRunLoop = (CFRunLoopRef)(((sHeader *)inData)->fContextData);
}
}
else
{
siResult = HandleRequest( inData );
}
}
catch( sInt32 err )
{
siResult = err;
}
if (pathStr != nil)
{
free(pathStr);
pathStr = nil;
}
return( siResult );
}
void CSearchNode::HandleMultipleNetworkTransitions ( void )
{
void *ptInfo = nil;
fTransitionCheckTime = time(nil) + 6;
if (fServerRunLoop != nil)
{
ptInfo = (void *)this;
CFRunLoopTimerContext c = {0, (void*)ptInfo, NULL, NULL, NetworkChangeSNPICopyStringCallback};
CFRunLoopTimerRef timer = CFRunLoopTimerCreate( NULL,
CFAbsoluteTimeGetCurrent() + 6,
0,
0,
0,
DoSNPINetworkChange,
(CFRunLoopTimerContext*)&c);
CFRunLoopAddTimer(fServerRunLoop, timer, kCFRunLoopDefaultMode);
if (timer) CFRelease(timer);
}
}
void CSearchNode::ReDiscoverNetwork(void)
{
if (time(nil) >= fTransitionCheckTime)
{
Initialize(); }
}
sInt32 CSearchNode::HandleRequest ( void *inData )
{
sInt32 siResult = eDSNoErr;
sHeader *pMsgHdr = nil;
try
{
pMsgHdr = (sHeader *)inData;
switch ( pMsgHdr->fType )
{
case kReleaseContinueData:
siResult = ReleaseContinueData( (sReleaseContinueData *)inData );
break;
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 kDoAttributeValueSearch:
case kDoAttributeValueSearchWithData:
siResult = AttributeValueSearch( (sDoAttrValueSearchWithData *)inData );
break;
case kCloseAttributeList:
siResult = CloseAttributeList( (sCloseAttributeList *)inData );
break;
case kCloseAttributeValueList:
siResult = CloseAttributeValueList( (sCloseAttributeValueList *)inData );
break;
case kDoPlugInCustomCall:
siResult = DoPlugInCustomCall( (sDoPlugInCustomCall *)inData );
break;
case kServerRunLoop:
siResult = eDSNoErr;
break;
default:
siResult = eNotHandledByThisNode;
break;
}
pMsgHdr->fResult = siResult;
}
catch( sInt32 err )
{
siResult = err;
}
catch ( ... )
{
siResult = ePlugInError;
}
return( siResult );
}
sInt32 CSearchNode::ReleaseContinueData ( sReleaseContinueData *inData )
{
sInt32 siResult = eDSNoErr;
if ( gSNContinue->RemoveItem( inData->fInContinueData ) != eDSNoErr )
{
siResult = eDSInvalidContext;
}
return( siResult );
}
sInt32 CSearchNode::OpenDirNode ( sOpenDirNode *inData )
{
sInt32 siResult = eDSOpenNodeFailed;
char *pathStr = nil;
sSearchContextData *pContext = nil;
sSearchConfig *aSearchConfigList = nil;
if ( inData != nil )
{
pathStr = ::dsGetPathFromListPriv( inData->fInDirNodeName, "/" );
if ( pathStr != nil )
{
fMutex.Wait();
aSearchConfigList = pSearchConfigList;
while (aSearchConfigList != nil)
{
if ( ::strcmp( pathStr, aSearchConfigList->fSearchNodeName ) == 0 )
{
pContext = MakeContextData();
if (pContext != nil)
{
pContext->pSearchListMutex = new DSMutexSemaphore();
pContext->fSearchConfigKey = aSearchConfigList->fSearchConfigKey;
if (strcmp(pathStr, kstrNetworkNodeName) == 0)
{
pContext->fSearchNodeList = BuildNetworkNodeList();
}
else {
pContext->fSearchNodeList = DupSearchListWithNewRefs(aSearchConfigList->fSearchNodeList);
}
if (aSearchConfigList->fSearchPolicy == kNetInfoSearchPolicy)
{
pContext->bAutoSearchList = true;
}
gSNNodeRef->AddItem( inData->fOutNodeRef, pContext );
siResult = eDSNoErr;
}
break;
}
aSearchConfigList = aSearchConfigList->fNext;
}
fMutex.Signal();
free( pathStr );
pathStr = nil;
}
}
return( siResult );
}
sInt32 CSearchNode::CloseDirNode ( sCloseDirNode *inData )
{
sInt32 siResult = eDSNoErr;
sSearchContextData *pContext = nil;
try
{
pContext = (sSearchContextData *) gSNNodeRef->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSInvalidNodeRef );
gSNNodeRef->RemoveItem( inData->fInNodeRef );
gSNContinue->RemoveItems( inData->fInNodeRef );
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CSearchNode::GetDirNodeInfo ( sGetDirNodeInfo *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiOffset = 0;
uInt32 uiNodeCnt = 0;
char *p = nil;
char *localNodeName = nil;
uInt32 uiCntr = 1;
uInt32 uiAttrCnt = 0;
CAttributeList *inAttrList = nil;
char *pAttrName = nil;
char *pData = nil;
sSearchContextData *pAttrContext = nil;
sSearchList *pListPtr = nil;
sSearchList *pListPtrToo = nil;
sSearchList *pListCustom = nil;
CBuff outBuff;
char *policyValue = nil;
sSearchContextData *pContext = nil;
sSearchConfig *aSearchConfig = nil;
CDataBuff *aRecData = nil;
CDataBuff *aAttrData = nil;
CDataBuff *aTmpData = nil;
uInt32 searchNodeNameBufLen = 0;
try
{
aRecData = new CDataBuff();
aAttrData = new CDataBuff();
aTmpData = new CDataBuff();
if ( inData == nil ) throw( (sInt32)eMemoryError );
pContext = (sSearchContextData *)gSNNodeRef->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSInvalidNodeRef );
fMutex.Wait();
aSearchConfig = FindSearchConfigWithKey(pContext->fSearchConfigKey);
if ( aSearchConfig == nil ) throw( (sInt32)eDSInvalidNodeRef );
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->Clear();
aAttrData->Clear();
aRecData->AppendShort( ::strlen( "dsAttrTypeStandard:SearchNodeInfo" ) );
aRecData->AppendString( "dsAttrTypeStandard:SearchNodeInfo" );
if (aSearchConfig->fSearchNodeName != nil)
{
searchNodeNameBufLen = strlen( aSearchConfig->fSearchNodeName );
aRecData->AppendShort( searchNodeNameBufLen );
searchNodeNameBufLen += 2;
aRecData->AppendString( aSearchConfig->fSearchNodeName );
}
else
{
aRecData->AppendShort( ::strlen( "SearchNodeInfo" ) );
aRecData->AppendString( "SearchNodeInfo" );
searchNodeNameBufLen = 16; }
while ( inAttrList->GetAttribute( uiCntr++, &pAttrName ) == eDSNoErr )
{
if ( (::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, kDS1AttrSearchPath ) == 0) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDS1AttrSearchPath ) );
aTmpData->AppendString( kDS1AttrSearchPath );
if ( inData->fInAttrInfoOnly == false )
{
uiNodeCnt = 0;
pListPtr = pContext->fSearchNodeList;
while ( pListPtr != nil )
{
uiNodeCnt++;
pListPtr = pListPtr->fNext;
}
aTmpData->AppendShort( uiNodeCnt );
pListPtr = pContext->fSearchNodeList;
while ( pListPtr != nil )
{
p = pListPtr->fNodeName;
aTmpData->AppendLong( ::strlen( p ) );
aTmpData->AppendString( p );
pListPtr = pListPtr->fNext;
}
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
if ( ( (::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, kDS1AttrNSPSearchPath ) == 0) ) &&
(pContext->fSearchConfigKey != eDSNetworkSearchNodeName) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDS1AttrNSPSearchPath ) );
aTmpData->AppendString( kDS1AttrNSPSearchPath );
if ( inData->fInAttrInfoOnly == false )
{
uiNodeCnt = 0;
pListPtr = GetNetInfoPaths(true, &localNodeName);
if ( pListPtr == nil ) throw( (sInt32)eSearchPathNotDefined );
if ( aSearchConfig->pConfigFromXML == nil
|| aSearchConfig->pConfigFromXML->IsDHCPLDAPEnabled() )
{
AddDefaultLDAPNodesLast(&pListPtr);
}
pListPtrToo = pListPtr;
while ( pListPtr != nil )
{
uiNodeCnt++;
pListPtr = pListPtr->fNext;
}
aTmpData->AppendShort( uiNodeCnt );
pListPtr = pListPtrToo;
while ( pListPtr != nil )
{
p = pListPtr->fNodeName;
aTmpData->AppendLong( ::strlen( p ) );
aTmpData->AppendString( p );
pListPtr = pListPtr->fNext;
}
CleanSearchListData( pListPtrToo );
pListPtrToo = nil;
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
if ( ( (::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, kDS1AttrLSPSearchPath ) == 0) ) &&
(pContext->fSearchConfigKey != eDSNetworkSearchNodeName) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDS1AttrLSPSearchPath ) );
aTmpData->AppendString( kDS1AttrLSPSearchPath );
if ( inData->fInAttrInfoOnly == false )
{
uiNodeCnt = 0;
pListPtr = GetLocalPaths(&localNodeName);
if ( pListPtr == nil ) throw( (sInt32)eSearchPathNotDefined );
pListPtrToo = pListPtr;
while ( pListPtr != nil )
{
uiNodeCnt++;
pListPtr = pListPtr->fNext;
}
aTmpData->AppendShort( uiNodeCnt );
pListPtr = pListPtrToo;
while ( pListPtr != nil )
{
p = pListPtr->fNodeName;
aTmpData->AppendLong( ::strlen( p ) );
aTmpData->AppendString( p );
pListPtr = pListPtr->fNext;
}
CleanSearchListData( pListPtrToo );
pListPtrToo = nil;
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
if ( ( (::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, kDS1AttrCSPSearchPath ) == 0) ) &&
(pContext->fSearchConfigKey != eDSNetworkSearchNodeName) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDS1AttrCSPSearchPath ) );
aTmpData->AppendString( kDS1AttrCSPSearchPath );
if ( inData->fInAttrInfoOnly == false )
{
if ( aSearchConfig->pConfigFromXML != nil )
{
pListCustom = aSearchConfig->pConfigFromXML->GetCustom();
}
pListPtr = GetLocalPaths(&localNodeName);
if ( pListPtr == nil ) throw( (sInt32)eSearchPathNotDefined );
pListPtrToo = pListPtr;
while ( pListPtrToo->fNext != nil )
{
pListPtrToo = pListPtrToo->fNext;
}
pListPtrToo->fNext = pListCustom;
uiNodeCnt = 0;
pListPtrToo = pListPtr;
while ( pListPtr != nil )
{
uiNodeCnt++;
pListPtr = pListPtr->fNext;
}
aTmpData->AppendShort( uiNodeCnt );
pListPtr = pListPtrToo;
while ( pListPtr != nil )
{
p = pListPtr->fNodeName;
aTmpData->AppendLong( ::strlen( p ) );
aTmpData->AppendString( p );
pListPtr = pListPtr->fNext;
}
CleanSearchListData( pListPtrToo );
pListPtrToo = nil;
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
if ( (::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, kDS1AttrSearchPolicy ) == 0) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDS1AttrSearchPolicy ) );
aTmpData->AppendString( kDS1AttrSearchPolicy );
if ( inData->fInAttrInfoOnly == false )
{
aTmpData->AppendShort( 1 );
if (aSearchConfig->fSearchPolicy == kNetInfoSearchPolicy)
{
policyValue = new char[1+strlen(kDS1AttrNSPSearchPath)];
strcpy(policyValue, kDS1AttrNSPSearchPath);
}
else if (aSearchConfig->fSearchPolicy == kLocalSearchPolicy)
{
policyValue = new char[1+strlen(kDS1AttrLSPSearchPath)];
strcpy(policyValue, kDS1AttrLSPSearchPath);
}
else if (aSearchConfig->fSearchPolicy == kCustomSearchPolicy)
{
policyValue = new char[1+strlen(kDS1AttrCSPSearchPath)];
strcpy(policyValue, kDS1AttrCSPSearchPath);
}
else
{
policyValue = new char[1+strlen("Unknown")];
strcpy(policyValue,"Unknown");
}
aTmpData->AppendLong( ::strlen( policyValue ) );
aTmpData->AppendString( policyValue );
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
if ( (::strcmp( pAttrName, kDSAttributesAll ) == 0) ||
(::strcmp( pAttrName, kDS1AttrReadOnlyNode ) == 0) )
{
aTmpData->Clear();
uiAttrCnt++;
aTmpData->AppendShort( ::strlen( kDS1AttrReadOnlyNode ) );
aTmpData->AppendString( kDS1AttrReadOnlyNode );
if ( inData->fInAttrInfoOnly == false )
{
aTmpData->AppendShort( 1 );
aTmpData->AppendLong( ::strlen( "ReadOnly" ) );
aTmpData->AppendString( "ReadOnly" );
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
}
fMutex.Signal();
aRecData->AppendShort( uiAttrCnt );
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();
pAttrContext->offset = uiOffset + 39 + searchNodeNameBufLen;
gSNNodeRef->AddItem( inData->fOutAttrListRef, pAttrContext );
}
else
{
siResult = eDSBufferTooSmall;
}
inData->fOutDataBuff->fBufferLength = inData->fOutDataBuff->fBufferSize;
}
catch( sInt32 err )
{
siResult = err;
fMutex.Signal();
}
if ( localNodeName != nil )
{
free( localNodeName );
localNodeName = nil;
}
if ( inAttrList != nil )
{
delete( inAttrList );
inAttrList = nil;
}
if (policyValue != nil)
{
delete( policyValue );
}
if ( aRecData != nil )
{
delete(aRecData);
aRecData = nil;
}
if ( aAttrData != nil )
{
delete(aAttrData);
aAttrData = nil;
}
if ( aTmpData != nil )
{
delete(aTmpData);
aTmpData = nil;
}
return( siResult );
}
sInt32 CSearchNode::GetRecordList ( sGetRecordList *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 recCount = 0;
bool done = false;
sSearchContinueData *pContinue = nil;
sSearchContinueData *pInContinue = nil;
eSearchState runState = keGetRecordList;
eSearchState lastState = keUnknownState;
CBuff inOutBuff;
sSearchContextData *pContext = nil;
sSearchConfig *aSearchConfig = nil;
bool bKeepOldBuffer = false;
try
{
pContext = (sSearchContextData *)gSNNodeRef->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSInvalidNodeRef );
if (pContext->pSearchListMutex == nil ) throw( (sInt32)eDSBadContextData);
fMutex.Wait();
pContext->pSearchListMutex->Wait();
aSearchConfig = FindSearchConfigWithKey(pContext->fSearchConfigKey);
if ( aSearchConfig == nil ) throw( (sInt32)eDSInvalidNodeRef );
if ( ( pContext->bListChanged ) && ( pContext->fSearchConfigKey != eDSNetworkSearchNodeName ) )
{
if ( inData->fIOContinueData != nil )
{
throw( (sInt32)eDSInvalidContinueData); }
else
{
CleanSearchListData( pContext->fSearchNodeList );
gSNContinue->RemoveItems( inData->fInNodeRef );
pContext->fSearchNodeList = DupSearchListWithNewRefs(aSearchConfig->fSearchNodeList);
if (aSearchConfig->fSearchPolicy == kNetInfoSearchPolicy)
{
pContext->bAutoSearchList = true;
}
else
{
pContext->bAutoSearchList = false;
}
pContext->bListChanged = false;
}
}
fMutex.Signal();
if ( pContext->fSearchNodeList == nil ) throw( (sInt32)eSearchPathNotDefined );
if ( inData->fIOContinueData != nil )
{
if ( gSNContinue->VerifyItem( inData->fIOContinueData ) == true )
{
pContinue = (sSearchContinueData *)::calloc( sizeof( sSearchContinueData ), sizeof( char ) );
if ( pContinue == nil ) throw( (sInt32)eMemoryAllocError );
pInContinue = (sSearchContinueData *)inData->fIOContinueData;
pContinue->fDirRef = pInContinue->fDirRef;
pContinue->fNodeRef = pInContinue->fNodeRef;
pContinue->fAttrOnly = pInContinue->fAttrOnly;
pContinue->fRecCount = pInContinue->fRecCount;
pContinue->fRecIndex = pInContinue->fRecIndex;
pContinue->fMetaTypes = pInContinue->fMetaTypes;
pContinue->fState = pInContinue->fState;
pContinue->fAliasList = pInContinue->fAliasList;
pContinue->fAliasAttribute = pInContinue->fAliasAttribute;
if (inData->fInDataBuff->fBufferSize != pInContinue->fDataBuff->fBufferSize)
{
if (pContinue->fState == keAddDataToBuff)
{
bKeepOldBuffer = true;
pContinue->fDataBuff = pInContinue->fDataBuff; pInContinue->fDataBuff = nil; }
else
{
pContinue->fDataBuff = ::dsDataBufferAllocatePriv( inData->fInDataBuff->fBufferSize );
if ( pContinue->fDataBuff == nil ) throw( (sInt32)eMemoryAllocError );
}
}
else
{
pContinue->fDataBuff = pInContinue->fDataBuff;
pInContinue->fDataBuff = nil;
}
pContinue->fContextData = pInContinue->fContextData;
pContinue->fLimitRecSearch = pInContinue->fLimitRecSearch;
pContinue->fTotalRecCount = pInContinue->fTotalRecCount;
pInContinue->fAliasList = nil;
pInContinue->fAliasAttribute = nil;
pInContinue->fContextData = nil;
gSNContinue->RemoveItem( inData->fIOContinueData );
pInContinue = nil;
inData->fIOContinueData = nil;
runState = pContinue->fState;
}
else
{
throw( (sInt32)eDSInvalidContinueData );
}
}
else
{
pContinue = (sSearchContinueData *)::calloc( 1, sizeof( sSearchContinueData ) );
if ( pContinue == nil ) throw( (sInt32)eMemoryAllocError );
pContinue->fDataBuff = ::dsDataBufferAllocatePriv( inData->fInDataBuff->fBufferSize );
if ( pContinue->fDataBuff == nil ) throw( (sInt32)eMemoryAllocError );
siResult = GetNextNodeRef( 0, &pContinue->fNodeRef, pContext );
if ( siResult != eDSNoErr ) throw( siResult );
pContinue->fDirRef = fDirRef;
pContinue->fRecIndex = 1;
pContinue->fTotalRecCount = 0;
pContinue->fLimitRecSearch = 0;
if (inData->fOutRecEntryCount >= 0)
{
pContinue->fLimitRecSearch = inData->fOutRecEntryCount;
}
DoAliasCheck( inData->fInRecTypeList, inData->fInAttribTypeList, pContinue );
}
siResult = inOutBuff.Initialize( inData->fInDataBuff, true );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = inOutBuff.SetBuffType( 'StdA' );
if ( siResult != eDSNoErr ) throw( siResult );
inData->fIOContinueData = nil;
inData->fOutRecEntryCount = 0;
while ( !done )
{
switch ( runState )
{
case keGetRecordList:
{
if (pContinue->fLimitRecSearch > pContinue->fTotalRecCount)
{
recCount = pContinue->fLimitRecSearch - pContinue->fTotalRecCount;
}
else
{
recCount = 0;
}
siResult = ::dsGetRecordList( pContinue->fNodeRef,
pContinue->fDataBuff,
inData->fInRecNameList,
inData->fInPatternMatch,
inData->fInRecTypeList,
inData->fInAttribTypeList,
inData->fInAttribInfoOnly,
&recCount,
&pContinue->fContextData );
pContinue->fRecCount = recCount;
pContinue->fRecIndex = 1;
lastState = keGetRecordList;
}
break;
case keAddDataToBuff:
{
siResult = AddDataToOutBuff( pContinue, &inOutBuff, pContext );
if (bKeepOldBuffer)
{
if (siResult == eDSNoErr)
{
if ( pContinue->fDataBuff != nil )
{
::dsDataBufferDeallocatePriv( pContinue->fDataBuff );
pContinue->fDataBuff = nil;
}
pContinue->fDataBuff = ::dsDataBufferAllocatePriv( inData->fInDataBuff->fBufferSize );
if ( pContinue->fDataBuff == nil ) throw( (sInt32)eMemoryAllocError );
bKeepOldBuffer = false;
}
}
lastState = keAddDataToBuff;
}
break;
case keGetAliases:
{
if (pContinue->fLimitRecSearch > pContinue->fTotalRecCount)
{
recCount = pContinue->fLimitRecSearch - pContinue->fTotalRecCount;
}
else
{
recCount = 0;
}
siResult = ::dsGetRecordList( pContinue->fNodeRef,
pContinue->fDataBuff,
inData->fInRecNameList, inData->fInPatternMatch,
pContinue->fAliasList,
pContinue->fAliasAttribute,
false, &recCount,
&pContinue->fContextData );
pContinue->fRecCount = recCount;
pContinue->fRecIndex = 1;
lastState = keGetAliases;
}
break;
case keExpandAliases:
{
siResult = ExpandAliases( pContinue, &inOutBuff, inData, nil, pContext );
lastState = keExpandAliases;
}
break;
case keGetNextNodeRef:
{
siResult = GetNextNodeRef( pContinue->fNodeRef, &pContinue->fNodeRef, pContext );
lastState = keGetNextNodeRef;
}
break;
case keSetContinueData:
{
switch ( lastState )
{
case keAddDataToBuff:
case keExpandAliases:
inOutBuff.GetDataBlockCount( &inData->fOutRecEntryCount );
pContinue->fTotalRecCount += inData->fOutRecEntryCount;
pContinue->fState = lastState;
inData->fIOContinueData = pContinue;
gSNContinue->AddItem( pContinue, inData->fInNodeRef );
siResult = eDSNoErr;
break;
case keGetRecordList:
case keGetNextNodeRef:
inOutBuff.GetDataBlockCount( &inData->fOutRecEntryCount );
pContinue->fTotalRecCount += inData->fOutRecEntryCount;
pContinue->fState = keGetRecordList;
if ( siResult == kEndOfSearchNodeList )
{
siResult = eDSNoErr;
inData->fIOContinueData = nil;
}
else
{
inData->fIOContinueData = pContinue;
gSNContinue->AddItem( pContinue, inData->fInNodeRef );
}
break;
case keBufferTooSmall:
if (pContinue->fContextData == nil) {
pContinue->fState = keAddDataToBuff;
}
else {
pContinue->fState = keGetRecordList;
}
inData->fIOContinueData = pContinue;
gSNContinue->AddItem( pContinue, inData->fInNodeRef );
siResult = eDSBufferTooSmall;
break;
default:
CShared::LogIt( 0x0F, "*** Invalid continue state = %l", lastState );
break;
}
}
break;
case keDone:
{
if ( pContinue != nil )
{
CSearchNode::ContinueDeallocProc( pContinue );
pContinue = nil;
}
done = true;
}
break;
default:
{
CShared::LogIt( 0x0F, "*** Unknown run state = %l", runState );
done = true;
}
break;
}
switch ( runState )
{
case keGetRecordList:
{
if ( siResult == eDSNoErr )
{
if ( pContinue->fRecCount != 0 )
{
runState = keAddDataToBuff;
}
else if (pContinue->fContextData == nil)
{
if ( pContinue->fAliasList != nil )
{
runState = keGetAliases;
}
else
{
runState = keGetNextNodeRef;
}
}
}
else if ( (siResult == eDSRecordNotFound ) ||
(siResult == eDSInvalidRecordName) ||
(siResult == eDSInvalidRecordType) )
{
if ( pContinue->fAliasList != nil )
{
runState = keGetAliases;
}
else
{
runState = keGetNextNodeRef;
}
}
else if (siResult == eDSBufferTooSmall)
{
lastState = keBufferTooSmall;
runState = keSetContinueData;
}
else {
runState = keGetNextNodeRef;
}
}
break;
case keAddDataToBuff:
{
uInt32 aRecCnt = 0;
inOutBuff.GetDataBlockCount(&aRecCnt);
if ( ( siResult == eDSNoErr ) || ( ( siResult == CBuff::kBuffFull ) && (aRecCnt > 0) ) )
{
inData->fOutRecEntryCount = aRecCnt;
if ((pContinue->fLimitRecSearch <= (pContinue->fTotalRecCount + inData->fOutRecEntryCount)) &&
(pContinue->fLimitRecSearch != 0))
{
pContinue->fTotalRecCount += inData->fOutRecEntryCount;
pContinue->fState = runState;
runState = keDone;
inData->fIOContinueData = nil;
siResult = eDSNoErr;
}
else
{
if ( siResult == CBuff::kBuffFull )
{
runState = keSetContinueData;
}
else if ( pContinue->fContextData )
{
lastState = keGetRecordList;
runState = keGetRecordList;
}
else
{
if ( pContinue->fAliasList != nil )
{
runState = keGetAliases;
}
else
{
runState = keGetNextNodeRef;
}
}
}
}
else
{
if ( siResult == CBuff::kBuffFull )
{
runState = keSetContinueData;
lastState = keBufferTooSmall;
}
else
{
runState = keDone;
}
}
}
break;
case keGetAliases:
{
if ( siResult == eDSNoErr )
{
if ( pContinue->fRecCount != 0 )
{
runState = keExpandAliases;
}
else if (pContinue->fContextData == nil)
{
runState = keGetNextNodeRef;
}
}
else {
runState = keGetNextNodeRef;
}
}
break;
case keExpandAliases:
{
if ( siResult == eDSNoErr )
{
if ( pContinue->fID > 5 )
{
if ( pContinue->fContextData )
{
pContinue->fContextData = nil;
pContinue->fID = 0;
}
}
else
{
inOutBuff.GetDataBlockCount( &inData->fOutRecEntryCount );
if ((pContinue->fLimitRecSearch <= (pContinue->fTotalRecCount + inData->fOutRecEntryCount)) &&
(pContinue->fLimitRecSearch != 0))
{
pContinue->fTotalRecCount += inData->fOutRecEntryCount;
pContinue->fState = runState;
runState = keDone;
inData->fIOContinueData = nil;
siResult = eDSNoErr;
}
else
{
if ( pContinue->fContextData )
{
runState = keGetAliases;
}
else
{
inOutBuff.GetDataBlockCount( &recCount );
if ( recCount == 0 )
{
runState = keGetNextNodeRef;
}
else
{
runState = keSetContinueData;
}
}
}
}
}
else
{
if ( siResult == CBuff::kBuffFull )
{
runState = keSetContinueData;
}
else
{
runState = keDone;
}
}
}
break;
case keGetNextNodeRef:
{
inOutBuff.GetDataBlockCount( &recCount );
if ( siResult == eDSNoErr )
{
if ( recCount == 0 )
{
runState = keGetRecordList;
}
else
{
runState = keSetContinueData;
}
}
else
{
if ( siResult == kEndOfSearchNodeList )
{
runState = keSetContinueData;
}
else
{
runState = keDone;
}
}
}
break;
case keSetContinueData:
case keDone:
case keError:
{
done = true;
}
break;
default:
{
CShared::LogIt( 0x0F, "*** Unknown transition state = %l", runState );
done = true;
}
break;
} }
pContext->pSearchListMutex->Signal();
}
catch( sInt32 err )
{
fMutex.Signal();
if (pContext->pSearchListMutex != nil)
{
pContext->pSearchListMutex->Signal();
}
siResult = err;
}
if ( (inData->fIOContinueData == nil) && (pContinue != nil ) )
{
CSearchNode::ContinueDeallocProc( pContinue );
pContinue = nil;
}
return( siResult );
}
sInt32 CSearchNode::GetRecordEntry ( sGetRecordEntry *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 uiIndex = 0;
uInt32 uiCount = 0;
uInt32 uiOffset = 0;
uInt32 uberOffset = 0;
char *pData = nil;
tRecordEntryPtr pRecEntry = nil;
sSearchContextData *pContext = nil;
CBuff inBuff;
uInt32 offset = 0;
uInt16 usTypeLen = 0;
char *pRecType = nil;
uInt16 usNameLen = 0;
char *pRecName = nil;
uInt16 usAttrCnt = 0;
uInt32 buffLen = 0;
try
{
if ( inData == nil ) throw( (sInt32)eMemoryError );
if ( inData->fInOutDataBuff == nil ) throw( (sInt32)eDSEmptyBuffer );
if (inData->fInOutDataBuff->fBufferSize == 0) throw( (sInt32)eDSEmptyBuffer );
siResult = inBuff.Initialize( inData->fInOutDataBuff );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = inBuff.GetDataBlockCount( &uiCount );
if ( siResult != eDSNoErr ) throw( siResult );
uiIndex = inData->fInRecEntryIndex;
if ((uiIndex > uiCount) || (uiIndex == 0)) throw( (sInt32)eDSInvalidIndex );
pData = inBuff.GetDataBlock( uiIndex, &uberOffset );
if ( pData == nil ) throw( (sInt32)eDSCorruptBuffer );
buffLen = inBuff.GetDataBlockLength( uiIndex );
pData += 4;
offset = 0;
if (2 + offset > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usTypeLen, pData, 2 );
pData += 2;
offset += 2;
pRecType = pData;
pData += usTypeLen;
offset += usTypeLen;
if (2 + offset > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usNameLen, pData, 2 );
pData += 2;
offset += 2;
pRecName = pData;
pData += usNameLen;
offset += usNameLen;
if (2 + offset > 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;
gSNNodeRef->AddItem( inData->fOutAttrListRef, pContext );
inData->fOutRecEntryPtr = pRecEntry;
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CSearchNode::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 = 0;
uInt32 buffSize = 0;
uInt32 buffLen = 0;
char *p = nil;
char *pAttrType = nil;
tDataBuffer *pDataBuff = nil;
tAttributeValueListRef attrValueListRef = 0;
tAttributeEntryPtr pAttribInfo = nil;
sSearchContextData *pAttrContext = nil;
sSearchContextData *pValueContext = nil;
try
{
if ( inData == nil ) throw( (sInt32)eMemoryError );
pAttrContext = (sSearchContextData *)gSNNodeRef->GetItemData( inData->fInAttrListRef );
if ( pAttrContext == nil ) throw( (sInt32)eDSBadContextData );
uiIndex = inData->fInAttrInfoIndex;
if (uiIndex == 0) throw( (sInt32)eDSInvalidIndex );
pDataBuff = inData->fInOutDataBuff;
if ( pDataBuff == nil ) throw( (sInt32)eDSNullDataBuff );
buffSize = pDataBuff->fBufferSize;
p = pDataBuff->fBufferData + pAttrContext->offset;
offset = pAttrContext->offset;
if (2 + offset > 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 (4 + offset > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen, p, 4 );
p += 4 + usAttrLen;
offset += 4 + usAttrLen;
}
uiOffset = offset;
if (4 + offset > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen, p, 4 );
p += 4;
offset += 4;
buffLen = offset + usAttrLen;
if (2 + offset > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrTypeLen, p, 2 );
pAttrType = p + 2;
p += 2 + usAttrTypeLen;
offset += 2 + usAttrTypeLen;
if (2 + offset > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueCnt, p, 2 );
p += 2;
offset += 2;
for ( i = 0; i < usValueCnt; i++ )
{
if (4 + offset > 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 );
attrValueListRef = inData->fOutAttrValueListRef;
pValueContext = MakeContextData();
if ( pValueContext == nil ) throw( (sInt32)eMemoryAllocError );
pValueContext->offset = uiOffset;
gSNNodeRef->AddItem( inData->fOutAttrValueListRef, pValueContext );
inData->fOutAttrInfoPtr = pAttribInfo;
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CSearchNode::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;
sSearchContextData *pValueContext = nil;
uInt32 buffSize = 0;
uInt32 buffLen = 0;
uInt32 attrLen = 0;
try
{
pValueContext = (sSearchContextData *)gSNNodeRef->GetItemData( inData->fInAttrValueListRef );
if ( pValueContext == nil ) throw( (sInt32)eDSBadContextData );
uiIndex = inData->fInAttrValueIndex;
if (uiIndex == 0) throw( (sInt32)eDSInvalidIndex );
pDataBuff = inData->fInOutDataBuff;
if ( pDataBuff == nil ) throw( (sInt32)eDSNullDataBuff );
buffSize = pDataBuff->fBufferSize;
p = pDataBuff->fBufferData + pValueContext->offset;
offset = pValueContext->offset;
if (4 + offset > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &attrLen, p, 4 );
buffLen = attrLen + pValueContext->offset + 4;
if (buffLen > buffSize) throw( (sInt32)eDSInvalidBuffFormat );
p += 4;
offset += 4;
if (2 + offset > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrNameLen, p, 2 );
p += 2 + usAttrNameLen;
offset += 2 + usAttrNameLen;
if (2 + offset > 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 (4 + offset > buffLen) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 4 );
p += 4 + usValueLen;
offset += 4 + usValueLen;
}
if (4 + offset > 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 ( usValueLen + offset > buffLen ) throw( (sInt32)eDSInvalidBuffFormat );
::memcpy( pAttrValue->fAttributeValueData.fBufferData, p, usValueLen );
pAttrValue->fAttributeValueID = 0x00;
inData->fOutAttrValue = pAttrValue;
}
catch( sInt32 err )
{
siResult = err;
}
return( siResult );
}
sInt32 CSearchNode::AttributeValueSearch ( sDoAttrValueSearchWithData *inData )
{
sInt32 siResult = eDSNoErr;
uInt32 recCount = 0;
bool done = false;
sSearchContinueData *pContinue = nil;
sSearchContinueData *pInContinue = nil;
eSearchState runState = keGetRecordList; eSearchState lastState = keUnknownState;
CBuff inOutBuff;
sSearchContextData *pContext = nil;
sSearchConfig *aSearchConfig = nil;
tDataList *allRecList = nil;
sInt32 allocResult = eDSNoErr;
bool bKeepOldBuffer = false;
try
{
allRecList = (tDataList *) calloc( 1, sizeof( tDataList ) );
allocResult = ::dsAppendStringToListPriv( allRecList, kDSRecordsAll );
if ( allocResult != eDSNoErr ) throw( allocResult );
pContext = (sSearchContextData *)gSNNodeRef->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSInvalidNodeRef );
if (pContext->pSearchListMutex == nil ) throw( (sInt32)eDSBadContextData);
fMutex.Wait();
pContext->pSearchListMutex->Wait();
aSearchConfig = FindSearchConfigWithKey(pContext->fSearchConfigKey);
if ( aSearchConfig == nil ) throw( (sInt32)eDSInvalidNodeRef );
if ( ( pContext->bListChanged ) && ( pContext->fSearchConfigKey != eDSNetworkSearchNodeName ) )
{
if ( inData->fIOContinueData != nil )
{
throw( (sInt32)eDSInvalidContinueData); }
else
{
CleanSearchListData( pContext->fSearchNodeList );
gSNContinue->RemoveItems( inData->fInNodeRef );
pContext->fSearchNodeList = DupSearchListWithNewRefs(aSearchConfig->fSearchNodeList);
if (aSearchConfig->fSearchPolicy == kNetInfoSearchPolicy)
{
pContext->bAutoSearchList = true;
}
else
{
pContext->bAutoSearchList = false;
}
pContext->bListChanged = false;
}
}
fMutex.Signal();
if ( pContext->fSearchNodeList == nil ) throw( (sInt32)eSearchPathNotDefined );
if ( inData->fIOContinueData != nil )
{
if ( gSNContinue->VerifyItem( inData->fIOContinueData ) == true )
{
pContinue = (sSearchContinueData *)::calloc( sizeof( sSearchContinueData ), sizeof(char) );
if ( pContinue == nil ) throw( (sInt32)eMemoryAllocError );
pInContinue = (sSearchContinueData *)inData->fIOContinueData;
pContinue->fDirRef = pInContinue->fDirRef;
pContinue->fNodeRef = pInContinue->fNodeRef;
pContinue->fAttrOnly = pInContinue->fAttrOnly;
pContinue->fRecCount = pInContinue->fRecCount;
pContinue->fRecIndex = pInContinue->fRecIndex;
pContinue->fMetaTypes = pInContinue->fMetaTypes;
pContinue->fState = pInContinue->fState;
pContinue->fAliasList = pInContinue->fAliasList;
pContinue->fAliasAttribute = pInContinue->fAliasAttribute;
if (inData->fOutDataBuff->fBufferSize != pInContinue->fDataBuff->fBufferSize)
{
if (pContinue->fState == keAddDataToBuff)
{
bKeepOldBuffer = true;
pContinue->fDataBuff = pInContinue->fDataBuff; pInContinue->fDataBuff = nil; }
else
{
pContinue->fDataBuff = ::dsDataBufferAllocatePriv( inData->fOutDataBuff->fBufferSize );
if ( pContinue->fDataBuff == nil ) throw( (sInt32)eMemoryAllocError );
}
}
else
{
pContinue->fDataBuff = pInContinue->fDataBuff;
pInContinue->fDataBuff = nil;
}
pContinue->fContextData = pInContinue->fContextData;
pContinue->fLimitRecSearch = pInContinue->fLimitRecSearch;
pContinue->fTotalRecCount = pInContinue->fTotalRecCount;
pInContinue->fAliasList = nil;
pInContinue->fAliasAttribute = nil;
pInContinue->fContextData = nil;
gSNContinue->RemoveItem( inData->fIOContinueData );
pInContinue = nil;
inData->fIOContinueData = nil;
runState = pContinue->fState;
}
else
{
throw( (sInt32)eDSInvalidContinueData );
}
}
else
{
pContinue = (sSearchContinueData *)::calloc( 1, sizeof( sSearchContinueData ) );
if ( pContinue == nil ) throw( (sInt32)eMemoryAllocError );
pContinue->fDataBuff = ::dsDataBufferAllocatePriv( inData->fOutDataBuff->fBufferSize );
if ( pContinue->fDataBuff == nil ) throw( (sInt32)eMemoryAllocError );
siResult = GetNextNodeRef( 0, &pContinue->fNodeRef, pContext );
if ( siResult != eDSNoErr ) throw( siResult );
pContinue->fDirRef = fDirRef;
pContinue->fRecIndex = 1;
pContinue->fTotalRecCount = 0;
pContinue->fLimitRecSearch = 0;
if (inData->fOutMatchRecordCount >= 0)
{
pContinue->fLimitRecSearch = inData->fOutMatchRecordCount;
}
tDataList myList;
::memset( &myList, 0, sizeof( tDataList ) );
allocResult = ::dsAppendStringToListPriv( &myList, inData->fInAttrType->fBufferData );
if ( allocResult == eDSNoErr )
{
DoAliasCheck( inData->fInRecTypeList, &myList, pContinue );
::dsDataListDeallocatePriv( &myList );
}
}
siResult = inOutBuff.Initialize( inData->fOutDataBuff, true );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = inOutBuff.SetBuffType( 'StdA' );
if ( siResult != eDSNoErr ) throw( siResult );
inData->fIOContinueData = nil;
inData->fOutMatchRecordCount = 0;
while ( !done )
{
switch ( runState )
{
case keGetRecordList:
{
if (pContinue->fLimitRecSearch > pContinue->fTotalRecCount)
{
recCount = pContinue->fLimitRecSearch - pContinue->fTotalRecCount;
}
else
{
recCount = 0;
}
if ( inData->fType == kDoAttributeValueSearchWithData )
{
siResult = ::dsDoAttributeValueSearchWithData(
pContinue->fNodeRef,
pContinue->fDataBuff,
inData->fInRecTypeList,
inData->fInAttrType,
inData->fInPattMatchType,
inData->fInPatt2Match,
inData->fInAttrTypeRequestList,
inData->fInAttrInfoOnly,
&recCount,
&pContinue->fContextData );
}
else
{
siResult = ::dsDoAttributeValueSearch( pContinue->fNodeRef,
pContinue->fDataBuff,
inData->fInRecTypeList,
inData->fInAttrType,
inData->fInPattMatchType,
inData->fInPatt2Match,
&recCount,
&pContinue->fContextData );
}
pContinue->fRecCount = recCount;
pContinue->fRecIndex = 1;
lastState = keGetRecordList;
}
break;
case keAddDataToBuff:
{
siResult = AddDataToOutBuff( pContinue, &inOutBuff, pContext );
if (bKeepOldBuffer)
{
if (siResult == eDSNoErr)
{
if ( pContinue->fDataBuff != nil )
{
::dsDataBufferDeallocatePriv( pContinue->fDataBuff );
pContinue->fDataBuff = nil;
}
pContinue->fDataBuff = ::dsDataBufferAllocatePriv( inData->fOutDataBuff->fBufferSize );
if ( pContinue->fDataBuff == nil ) throw( (sInt32)eMemoryAllocError );
bKeepOldBuffer = false;
}
}
lastState = keAddDataToBuff;
}
break;
case keGetAliases:
{
if (pContinue->fLimitRecSearch > pContinue->fTotalRecCount)
{
recCount = pContinue->fLimitRecSearch - pContinue->fTotalRecCount;
}
else
{
recCount = 0;
}
siResult = ::dsGetRecordList( pContinue->fNodeRef,
pContinue->fDataBuff,
allRecList,
inData->fInPattMatchType,
pContinue->fAliasList,
pContinue->fAliasAttribute,
false,
&recCount,
&pContinue->fContextData );
pContinue->fRecCount = recCount;
pContinue->fRecIndex = 1;
lastState = keGetAliases;
}
break;
case keExpandAliases:
{
siResult = ExpandAliases( pContinue, &inOutBuff, nil, inData, pContext );
lastState = keExpandAliases;
}
break;
case keGetNextNodeRef:
{
siResult = GetNextNodeRef( pContinue->fNodeRef, &pContinue->fNodeRef, pContext );
lastState = keGetNextNodeRef;
}
break;
case keSetContinueData:
{
switch ( lastState )
{
case keAddDataToBuff:
case keExpandAliases:
inOutBuff.GetDataBlockCount( &inData->fOutMatchRecordCount );
pContinue->fTotalRecCount += inData->fOutMatchRecordCount;
pContinue->fState = lastState;
inData->fIOContinueData = pContinue;
gSNContinue->AddItem( pContinue, inData->fInNodeRef );
siResult = eDSNoErr;
break;
case keGetRecordList:
case keGetNextNodeRef:
inOutBuff.GetDataBlockCount( &inData->fOutMatchRecordCount );
pContinue->fTotalRecCount += inData->fOutMatchRecordCount;
pContinue->fState = keGetRecordList;
if ( siResult == kEndOfSearchNodeList )
{
siResult = eDSNoErr;
inData->fIOContinueData = nil;
}
else
{
inData->fIOContinueData = pContinue;
gSNContinue->AddItem( pContinue, inData->fInNodeRef );
}
break;
case keBufferTooSmall:
if (pContinue->fContextData == nil) {
pContinue->fState = keAddDataToBuff;
}
else {
pContinue->fState = keGetRecordList;
}
inData->fIOContinueData = pContinue;
gSNContinue->AddItem( pContinue, inData->fInNodeRef );
siResult = eDSBufferTooSmall;
break;
default:
CShared::LogIt( 0x0F, "*** Invalid continue state = %l", lastState );
break;
}
}
break;
case keDone:
{
if ( pContinue != nil )
{
CSearchNode::ContinueDeallocProc( pContinue );
pContinue = nil;
}
done = true;
}
break;
default:
{
CShared::LogIt( 0x0F, "*** Unknown run state = %l", runState );
done = true;
}
break;
}
switch ( runState )
{
case keGetRecordList:
{
if ( siResult == eDSNoErr )
{
if ( pContinue->fRecCount != 0 )
{
runState = keAddDataToBuff;
}
else if (pContinue->fContextData == nil)
{
if ( pContinue->fAliasList != nil )
{
runState = keGetAliases;
}
else
{
runState = keGetNextNodeRef;
}
}
}
else if ( (siResult == eDSRecordNotFound ) ||
(siResult == eDSInvalidRecordName) ||
(siResult == eDSInvalidRecordType) )
{
if ( pContinue->fAliasList != nil )
{
runState = keGetAliases;
}
else
{
runState = keGetNextNodeRef;
}
}
else if (siResult == eDSBufferTooSmall)
{
lastState = keBufferTooSmall;
runState = keSetContinueData;
}
else {
runState = keGetNextNodeRef;
}
}
break;
case keAddDataToBuff:
{
uInt32 aRecCnt = 0;
inOutBuff.GetDataBlockCount(&aRecCnt);
if ( ( siResult == eDSNoErr ) || ( ( siResult == CBuff::kBuffFull ) && (aRecCnt > 0) ) )
{
inData->fOutMatchRecordCount = aRecCnt;
if ((pContinue->fLimitRecSearch <= (pContinue->fTotalRecCount + inData->fOutMatchRecordCount)) &&
(pContinue->fLimitRecSearch != 0))
{
pContinue->fTotalRecCount += inData->fOutMatchRecordCount;
pContinue->fState = runState;
runState = keDone;
inData->fIOContinueData = nil;
siResult = eDSNoErr;
}
else
{
if ( siResult == CBuff::kBuffFull )
{
runState = keSetContinueData;
}
else if ( pContinue->fContextData )
{
lastState = keGetRecordList;
runState = keGetRecordList;
}
else
{
if ( pContinue->fAliasList != nil )
{
runState = keGetAliases;
}
else
{
runState = keGetNextNodeRef;
}
}
}
}
else
{
if ( siResult == CBuff::kBuffFull )
{
runState = keSetContinueData;
lastState = keBufferTooSmall;
}
else
{
runState = keDone;
}
}
}
break;
case keGetAliases:
{
if ( siResult == eDSNoErr )
{
if ( pContinue->fRecCount != 0 )
{
runState = keExpandAliases;
}
else if (pContinue->fContextData == nil)
{
runState = keGetNextNodeRef;
}
}
else {
runState = keGetNextNodeRef;
}
}
break;
case keExpandAliases:
{
if ( siResult == eDSNoErr )
{
if ( pContinue->fID > 5 )
{
if ( pContinue->fContextData )
{
pContinue->fContextData = nil;
pContinue->fID = 0;
}
}
else
{
inOutBuff.GetDataBlockCount( &inData->fOutMatchRecordCount );
if ((pContinue->fLimitRecSearch <= (pContinue->fTotalRecCount + inData->fOutMatchRecordCount)) &&
(pContinue->fLimitRecSearch != 0))
{
pContinue->fTotalRecCount += inData->fOutMatchRecordCount;
pContinue->fState = runState;
runState = keDone;
inData->fIOContinueData = nil;
siResult = eDSNoErr;
}
else
{
if ( pContinue->fContextData )
{
runState = keGetAliases;
}
else
{
inOutBuff.GetDataBlockCount( &recCount );
if ( recCount == 0 )
{
runState = keGetNextNodeRef;
}
else
{
runState = keSetContinueData;
}
}
}
}
}
else
{
if ( siResult == CBuff::kBuffFull )
{
runState = keSetContinueData;
}
else
{
runState = keDone;
}
}
}
break;
case keGetNextNodeRef:
{
inOutBuff.GetDataBlockCount( &recCount );
if ( siResult == eDSNoErr )
{
if ( recCount == 0 )
{
runState = keGetRecordList;
}
else
{
runState = keSetContinueData;
}
}
else
{
if ( siResult == kEndOfSearchNodeList )
{
runState = keSetContinueData;
}
else
{
runState = keDone;
}
}
}
break;
case keSetContinueData:
case keDone:
case keError:
{
done = true;
}
break;
default:
{
CShared::LogIt( 0x0F, "*** Unknown transition state = %l", runState );
done = true;
}
break;
} }
pContext->pSearchListMutex->Signal();
}
catch( sInt32 err )
{
fMutex.Signal();
if (pContext->pSearchListMutex != nil)
{
pContext->pSearchListMutex->Signal();
}
siResult = err;
}
if ( (inData->fIOContinueData == nil) && (pContinue != nil ) )
{
CSearchNode::ContinueDeallocProc( pContinue );
pContinue = nil;
}
if (allRecList != nil)
{
::dsDataListDeallocatePriv( allRecList );
free(allRecList);
allRecList = nil;
}
return( siResult );
}
sInt32 CSearchNode::GetNextNodeRef ( tDirNodeReference inNodeRef, tDirNodeReference *outNodeRef, sSearchContextData *inContext )
{
sInt32 siResult = kEndOfSearchNodeList;
sSearchList *pNodeList = nil;
sSearchConfig *aSearchConfig = nil;
tDirNodeReference aNodeRef = inNodeRef;
uInt32 nodeIndex = 0;
pNodeList = (sSearchList *)inContext->fSearchNodeList;
if (aNodeRef != 0) {
while ( pNodeList != nil )
{
nodeIndex++;
if ( aNodeRef == pNodeList->fNodeRef )
{
pNodeList = pNodeList->fNext;
break;
}
pNodeList = pNodeList->fNext;
}
}
if (nodeIndex == 1) {
bool bRecheckNI = false;
if (inContext->bAutoSearchList)
{
if (pNodeList != nil)
{
if ( pNodeList->fNodeName != nil)
{
if (strncmp(pNodeList->fNodeName,"/NetInfo",8) != 0)
{
bRecheckNI = true;
} } } else
{
bRecheckNI = true;
} if (bRecheckNI)
{
tDataList *pNodeNameDL = nil;
pNodeNameDL = ::dsBuildListFromStringsPriv( "NetInfo", "..", nil );
if (pNodeNameDL != nil)
{
sInt32 openResult = eDSNoErr;
openResult = dsOpenDirNode( fDirRef, pNodeNameDL, &aNodeRef );
if ( openResult == eDSNoErr )
{
sSearchList *aSearchNodeList = nil;
dsCloseDirNode(aNodeRef);
DoNetInfoDefault(&aSearchNodeList);
if (aSearchNodeList != nil)
{
fMutex.Wait();
aSearchConfig = FindSearchConfigWithKey(inContext->fSearchConfigKey);
CleanSearchListData( inContext->fSearchNodeList );
CleanSearchListData( aSearchConfig->fSearchNodeList );
aSearchConfig->fSearchNodeList = aSearchNodeList;
fMutex.Signal();
if ( aSearchConfig->pConfigFromXML == nil
|| aSearchConfig->pConfigFromXML->IsDHCPLDAPEnabled() )
{
AddDefaultLDAPNodesLast(&aSearchNodeList);
}
inContext->fSearchNodeList = DupSearchListWithNewRefs(aSearchNodeList);
inContext->bListChanged = false;
pNodeList = ((sSearchList *)inContext->fSearchNodeList)->fNext;
}
}
dsDataListDeAllocate( fDirRef, pNodeNameDL, false );
free(pNodeNameDL);
pNodeNameDL = nil;
}
}
}
}
while ( pNodeList != nil )
{
if ( pNodeList->fOpened == false )
{
siResult = ::dsOpenDirNode( fDirRef, pNodeList->fDataList, &pNodeList->fNodeRef );
if ( siResult == eDSNoErr )
{
*outNodeRef = pNodeList->fNodeRef;
pNodeList->fOpened = true;
break;
}
else
{
siResult = kEndOfSearchNodeList;
}
}
else
{
*outNodeRef = pNodeList->fNodeRef;
siResult = eDSNoErr;
break;
}
pNodeList = pNodeList->fNext;
}
return( siResult );
}
tDataList* CSearchNode::GetNodePath ( tDirNodeReference inNodeRef, sSearchContextData *inContext )
{
tDataList *pResult = nil;
sSearchList *pNodeList = nil;
pNodeList = (sSearchList *)inContext->fSearchNodeList;
while ( pNodeList != nil )
{
if ( inNodeRef == pNodeList->fNodeRef )
{
pResult = pNodeList->fDataList;
break;
}
pNodeList = pNodeList->fNext;
}
return( pResult );
}
sSearchContextData* CSearchNode::MakeContextData ( void )
{
sSearchContextData *pOut = nil;
pOut = (sSearchContextData *) ::calloc( 1, sizeof(sSearchContextData) );
if ( pOut != nil )
{
pOut->fSearchNodeList = nil;
pOut->bListChanged = false;
pOut->pSearchListMutex = nil;
pOut->fSearchNode = this;
pOut->bAutoSearchList = false;
}
return( pOut );
}
sInt32 CSearchNode::CleanContextData ( sSearchContextData *inContext )
{
sInt32 siResult = eDSNoErr;
DSMutexSemaphore *ourMutex = nil;
if (( inContext == nil ) || ( gSearchNode == nil ))
{
siResult = eDSBadContextData;
}
else
{
ourMutex = inContext->pSearchListMutex;
if (ourMutex != nil)
{
ourMutex->Wait();
if (inContext->fSearchNodeList != nil && inContext->fSearchNode != nil)
{
gSearchNode->CleanSearchListData( inContext->fSearchNodeList );
inContext->fSearchNodeList = nil;
}
inContext->bListChanged = false;
inContext->offset = 0;
inContext->fSearchConfigKey = 0;
inContext->pSearchListMutex = nil;
inContext->bAutoSearchList = false;
delete(ourMutex);
ourMutex = nil;
}
free( inContext );
inContext = nil;
}
return( siResult );
}
void CSearchNode::DoAliasCheck ( tDataList *inRecTypeList, tDataList *inAttrTypeList, sSearchContinueData *inContinue )
{
sInt32 siIndex = 1;
char *cpString = nil;
bool bUserAlias = false;
bool bGroupAlias = false;
CRecTypeList *clpRecTypeList = nil;
CAttributeList *clpAttrTypeList = nil;
try
{
clpRecTypeList = new CRecTypeList( inRecTypeList );
if ( clpRecTypeList == nil ) throw( (sInt32)eDSEmptyRecordTypeList );
if (clpRecTypeList->GetCount() == 0) throw( (sInt32)eDSEmptyRecordTypeList );
while ( clpRecTypeList->GetAttribute( siIndex++, &cpString ) == eDSNoErr )
{
if ( (::strcmp( cpString, kDSStdRecordTypeUsers ) == 0) || (::strcmp( cpString, kDSStdUserNamesMeta ) == 0) )
{
bUserAlias = true;
}
else if ( ::strcmp( cpString, kDSStdRecordTypeGroups ) == 0 )
{
bGroupAlias = true;
}
}
if ( (bUserAlias == true) && (bGroupAlias == true) )
{
inContinue->fAliasList = ::dsBuildListFromStringsPriv( kDSStdRecordTypeUserAliases, kDSStdRecordTypeGroupAliases, nil );
}
else if ( bUserAlias == true )
{
inContinue->fAliasList = ::dsBuildListFromStringsPriv( kDSStdRecordTypeUserAliases, nil );
}
else if ( bGroupAlias == true )
{
inContinue->fAliasList = ::dsBuildListFromStringsPriv( kDSStdRecordTypeGroupAliases, nil );
}
inContinue->fMetaTypes = keNullMetaType;
if ( (bUserAlias == true) || (bGroupAlias == true) )
{
inContinue->fAliasAttribute = ::dsBuildListFromStringsPriv( kDS1AttrAliasData, nil );
clpAttrTypeList = new CAttributeList( inAttrTypeList );
if ( clpAttrTypeList != nil )
{
siIndex = 1;
while ( clpAttrTypeList->GetAttribute( siIndex++, &cpString ) == eDSNoErr )
{
if ( ::strcmp( cpString, kStandardTargetAlias ) == 0 )
{
inContinue->fMetaTypes |= keTargetAlias;
}
else if ( ::strcmp( cpString, kStandardSourceAlias ) == 0 )
{
inContinue->fMetaTypes |= keSourceAlias;
}
else if ( ::strcmp( cpString, kDSAttributesAll ) == 0 )
{
inContinue->fMetaTypes |= keTargetAlias;
inContinue->fMetaTypes |= keSourceAlias;
}
}
delete( clpAttrTypeList );
clpAttrTypeList = nil;
}
}
}
catch( sInt32 err )
{
}
if ( clpRecTypeList != nil )
{
delete( clpRecTypeList );
clpRecTypeList = nil;
}
if ( clpAttrTypeList != nil )
{
delete( clpAttrTypeList );
clpAttrTypeList = nil;
}
}
sInt32 CSearchNode::AddDataToOutBuff ( sSearchContinueData *inContinue, CBuff *inOutBuff, sSearchContextData *inContext, tDataList *inTarget )
{
uInt32 i = 1;
uInt32 j = 1;
sInt32 attrCnt = 0;
sInt32 siResult = eDSNoErr;
char *cpRecType = nil;
char *cpRecName = nil;
tRecordEntry *pRecEntry = nil;
tAttributeListRef attrListRef = 0;
tDataList *pSourcePath = nil;
tDataList *pTargetPath = nil;
tDataNode *pDataNode = nil;
tAttributeValueListRef valueRef = 0;
tAttributeEntry *pAttrEntry = nil;
tAttributeValueEntry *pValueEntry = nil;
CDataBuff *aRecData = nil;
CDataBuff *aAttrData = nil;
CDataBuff *aTmpData = nil;
try
{
aRecData = new CDataBuff();
aAttrData = new CDataBuff();
aTmpData = new CDataBuff();
while ( (inContinue->fRecIndex <= inContinue->fRecCount) && (siResult == eDSNoErr) )
{
siResult = ::dsGetRecordEntry( inContinue->fNodeRef, inContinue->fDataBuff, inContinue->fRecIndex, &attrListRef, &pRecEntry );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = ::dsGetRecordTypeFromEntry( pRecEntry, &cpRecType );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = ::dsGetRecordNameFromEntry( pRecEntry, &cpRecName );
if ( siResult != eDSNoErr ) throw( siResult );
aRecData->Clear();
aAttrData->Clear();
aTmpData->Clear();
aRecData->AppendShort( ::strlen( cpRecType ) );
aRecData->AppendString( cpRecType );
aRecData->AppendShort( ::strlen( cpRecName ) );
aRecData->AppendString( cpRecName );
if ( cpRecName != nil )
{
free( cpRecName );
cpRecName = nil;
}
if ( ((::strcmp( cpRecType, kDSStdRecordTypeUsers ) == 0) ||
(::strcmp( cpRecType, kDSStdUserNamesMeta ) == 0) ||
(::strcmp( cpRecType, kDSStdRecordTypeGroups ) == 0)) &&
((inContinue->fMetaTypes & keTargetAlias) || (inContinue->fMetaTypes & keSourceAlias) ) )
{
attrCnt = 1;
if ( (inContinue->fMetaTypes & keTargetAlias) && (inContinue->fMetaTypes & keSourceAlias) )
{
attrCnt = 2;
}
pSourcePath = GetNodePath( inContinue->fNodeRef, inContext );
if ( inTarget != nil )
{
pTargetPath = inTarget;
}
else
{
pTargetPath = GetNodePath( inContinue->fNodeRef, inContext );
}
aRecData->AppendShort( pRecEntry->fRecordAttributeCount + attrCnt );
if ( pTargetPath != nil )
{
if ( inContinue->fMetaTypes & keTargetAlias )
{
aTmpData->AppendShort( ::strlen( kStandardTargetAlias ) );
aTmpData->AppendString( kStandardTargetAlias );
aTmpData->AppendShort( pTargetPath->fDataNodeCount );
i = 1;
while ( ::dsDataListGetNodeAllocPriv( pTargetPath, i++, &pDataNode ) == eDSNoErr )
{
aTmpData->AppendLong( ::strlen( pDataNode->fBufferData ) );
aTmpData->AppendString( pDataNode->fBufferData );
::dsDataBufferDeallocatePriv( pDataNode );
pDataNode = nil;
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
}
if ( pSourcePath != nil )
{
if ( inContinue->fMetaTypes & keSourceAlias )
{
aTmpData->AppendShort( ::strlen( kStandardSourceAlias ) );
aTmpData->AppendString( kStandardSourceAlias );
aTmpData->AppendShort( pSourcePath->fDataNodeCount );
i = 1;
while ( ::dsDataListGetNodeAllocPriv( pSourcePath, i++, &pDataNode ) == eDSNoErr )
{
aTmpData->AppendLong( ::strlen( pDataNode->fBufferData ) );
aTmpData->AppendString( pDataNode->fBufferData );
::dsDataBufferDeallocatePriv( pDataNode );
pDataNode = nil;
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
}
}
}
else
{
aRecData->AppendShort( pRecEntry->fRecordAttributeCount );
}
if ( cpRecType != nil )
{
free( cpRecType );
cpRecType = nil;
}
if ( pRecEntry->fRecordAttributeCount != 0 )
{
for ( i = 1; i <= pRecEntry->fRecordAttributeCount; i++ )
{
siResult = ::dsGetAttributeEntry( inContinue->fNodeRef, inContinue->fDataBuff, attrListRef, i, &valueRef, &pAttrEntry );
if ( siResult != eDSNoErr ) throw( siResult );
aTmpData->AppendShort( ::strlen( pAttrEntry->fAttributeSignature.fBufferData ) );
aTmpData->AppendString( pAttrEntry->fAttributeSignature.fBufferData );
if ( inContinue->fAttrOnly == false )
{
aTmpData->AppendShort( pAttrEntry->fAttributeValueCount );
for ( j = 1; j <= pAttrEntry->fAttributeValueCount; j++ )
{
siResult = dsGetAttributeValue( inContinue->fNodeRef, inContinue->fDataBuff, j, valueRef, &pValueEntry );
if ( siResult != eDSNoErr ) throw( siResult );
aTmpData->AppendLong( ::strlen( pValueEntry->fAttributeValueData.fBufferData ) );
aTmpData->AppendString( pValueEntry->fAttributeValueData.fBufferData );
dsDeallocAttributeValueEntry(fDirRef, pValueEntry);
pValueEntry = nil;
}
}
aAttrData->AppendLong( aTmpData->GetLength() );
aAttrData->AppendBlock( aTmpData->GetData(), aTmpData->GetLength() );
aTmpData->Clear();
dsCloseAttributeValueList(valueRef);
dsDeallocAttributeEntry(fDirRef, pAttrEntry);
pAttrEntry = nil;
}
}
if ( (pRecEntry->fRecordAttributeCount + attrCnt) != 0 )
{
aRecData->AppendBlock( aAttrData->GetData(), aAttrData->GetLength() );
}
siResult = inOutBuff->AddData( aRecData->GetData(), aRecData->GetLength() );
if ( siResult == eDSNoErr )
{
inContinue->fRecIndex++;
}
dsCloseAttributeList(attrListRef);
dsDeallocRecordEntry(fDirRef, pRecEntry);
pRecEntry = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( cpRecType != nil )
{
free( cpRecType );
cpRecType = nil;
}
if ( cpRecName != nil )
{
free( cpRecName );
cpRecName = 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 CSearchNode::ExpandAliases ( sSearchContinueData *inContinue,
CBuff *inOutBuff,
sGetRecordList *inGRLData,
sDoAttrValueSearchWithData *inDAVSData,
sSearchContextData *inContext )
{
sInt32 siResult = eDSNoErr;
bool done = false;
char *cpRecType = nil;
char *cpAliasType = nil; tRecordEntry *pRecEntry = nil;
tAttributeListRef attrListRef = 0;
tAttributeValueListRef valueRef = 0;
tAttributeEntry *pAttrEntry = nil;
tAttributeValueEntry *pValueEntry = nil;
CAliases cAlias;
tDataList *pNameList = nil;
tDataList *pPathList = nil;
tDataList *pTypeList = nil;
tDirNodeReference nodeRef = 0;
tDataBuffer *tDataBuff = nil;
tContextData pContextData = nil;
sSearchContinueData myContinue;
try
{
if ((inGRLData == nil) && (inDAVSData == nil)) throw( (sInt32)eMemoryAllocError );
if ( inGRLData != nil )
{
tDataBuff = ::dsDataBufferAllocatePriv( inGRLData->fInDataBuff->fBufferSize );
}
else
{
tDataBuff = ::dsDataBufferAllocatePriv( inDAVSData->fOutDataBuff->fBufferSize );
}
if ( tDataBuff == nil ) throw( (sInt32)eMemoryAllocError );
::memset( &myContinue, 0, sizeof( sSearchContinueData ) );
inContinue->fID++;
while ( (inContinue->fRecIndex <= inContinue->fRecCount) && (siResult == eDSNoErr) && !done )
{
siResult = ::dsGetRecordEntry( inContinue->fNodeRef, inContinue->fDataBuff, inContinue->fRecIndex, &attrListRef, &pRecEntry );
if ( siResult == eDSNoErr )
{
siResult = ::dsGetRecordTypeFromEntry( pRecEntry, &cpRecType );
if ( (siResult == eDSNoErr) && (pRecEntry->fRecordAttributeCount != 0) )
{
siResult = ::dsGetAttributeEntry( inContinue->fNodeRef, inContinue->fDataBuff, attrListRef, 1, &valueRef, &pAttrEntry );
if ( siResult == eDSNoErr )
{
if ( ::strcmp( pAttrEntry->fAttributeSignature.fBufferData, kDS1AttrAliasData ) == 0 )
{
siResult = ::dsGetAttributeValue( inContinue->fNodeRef, inContinue->fDataBuff, 1, valueRef, &pValueEntry );
}
else
{
siResult = eDSInvalidIndex;
}
}
dsCloseAttributeValueList(valueRef);
if (pAttrEntry != nil)
{
dsDeallocAttributeEntry(fDirRef, pAttrEntry);
pAttrEntry = nil;
}
}
else
{
siResult = eDSInvalidIndex;
}
}
if ( siResult == eDSNoErr )
{
siResult = cAlias.Initialize( pValueEntry->fAttributeValueData.fBufferData, pValueEntry->fAttributeValueData.fBufferLength );
if ( siResult == eDSNoErr )
{
siResult = cAlias.GetRecordType( &cpAliasType );
if ( siResult == eDSNoErr )
{
if ( (::strcmp( cpRecType, kDSStdRecordTypeUserAliases ) == 0) &&
(::strcmp( cpAliasType, kDSStdRecordTypeUsers ) == 0) )
{
pTypeList = ::dsBuildListFromStringsPriv( kDSStdRecordTypeUsers, nil );
}
else if ( (::strcmp( cpRecType, kDSStdRecordTypeGroupAliases ) == 0) &&
(::strcmp( cpAliasType, kDSStdRecordTypeGroups ) == 0) )
{
pTypeList = ::dsBuildListFromStringsPriv( kDSStdRecordTypeGroups, nil );
}
else
{
siResult = eDSInvalidIndex;
}
}
inContinue->fRecIndex++;
done = true;
if ( siResult == eDSNoErr )
{
siResult = eMemoryAllocError;
pNameList = ::dsDataListAllocatePriv();
if ( pNameList != nil )
{
siResult = cAlias.GetRecordName( pNameList );
if ( siResult == eDSNoErr )
{
siResult = eMemoryAllocError;
pPathList = ::dsDataListAllocatePriv();
if ( pPathList != nil )
{
siResult = cAlias.GetRecordLocation( pPathList );
if ( siResult == eDSNoErr )
{
siResult = ::dsOpenDirNode( fDirRef, pPathList, &nodeRef );
if ( siResult == eDSNoErr )
{
if ( inGRLData != nil )
{
siResult = ::dsGetRecordList( nodeRef,
tDataBuff,
pNameList,
inGRLData->fInPatternMatch,
pTypeList,
inGRLData->fInAttribTypeList,
inGRLData->fInAttribInfoOnly,
&myContinue.fRecCount,
&pContextData );
}
else
{
if ( inDAVSData->fType == kDoAttributeValueSearchWithData )
{
siResult = ::dsDoAttributeValueSearchWithData(
nodeRef,
tDataBuff,
pTypeList,
inDAVSData->fInAttrType,
inDAVSData->fInPattMatchType,
inDAVSData->fInPatt2Match,
inDAVSData->fInAttrTypeRequestList,
inDAVSData->fInAttrInfoOnly,
&myContinue.fRecCount,
&pContextData );
}
else
{
siResult = ::dsDoAttributeValueSearch(
nodeRef,
tDataBuff,
pTypeList,
inDAVSData->fInAttrType,
inDAVSData->fInPattMatchType,
inDAVSData->fInPatt2Match,
&myContinue.fRecCount,
&pContextData );
}
}
if ( siResult == eDSNoErr )
{
myContinue.fNodeRef = inContinue->fNodeRef;
myContinue.fRecIndex = 1;
myContinue.fRecCount = 1;
if ( inGRLData != nil )
{
myContinue.fAttrOnly = inGRLData->fInAttribInfoOnly;
}
myContinue.fMetaTypes = inContinue->fMetaTypes;
myContinue.fDataBuff = tDataBuff;
siResult = AddDataToOutBuff( &myContinue, inOutBuff, inContext, pPathList );
if ( siResult == CBuff::kBuffFull )
{
inContinue->fRecIndex--;
done = true;
}
else
{
done = false;
}
}
::dsCloseDirNode( nodeRef );
}
}
(void)::dsDataListDeallocatePriv( pPathList );
free( pPathList );
pPathList = nil;
}
}
(void)::dsDataListDeallocatePriv( pNameList );
free( pNameList );
pNameList = nil;
}
(void)::dsDataListDeallocatePriv( pTypeList );
free( pTypeList );
pTypeList = nil;
}
}
}
if (pValueEntry != nil)
{
dsDeallocAttributeValueEntry(fDirRef, pValueEntry);
pValueEntry = nil;
}
if ( cpRecType != nil )
{
free( cpRecType );
cpRecType = nil;
}
dsCloseAttributeList(attrListRef);
dsDeallocRecordEntry(fDirRef, pRecEntry);
pRecEntry = nil;
}
if ( tDataBuff != nil )
{
::dsDataBufferDeallocatePriv( tDataBuff );
tDataBuff = nil;
}
}
catch( sInt32 err )
{
siResult = err;
}
if ( cpRecType != nil )
{
free( cpRecType );
cpRecType = nil;
}
return( eDSNoErr );
}
sInt32 CSearchNode::DoPlugInCustomCall ( sDoPlugInCustomCall *inData )
{
sInt32 siResult = eDSNoErr;
unsigned long aRequest = 0;
sInt32 xmlDataLength = 0;
CFDataRef xmlData = nil;
CFDictionaryRef dhcpLDAPdict = nil;
CFMutableArrayRef cspArray = nil;
unsigned long bufLen = 0;
sSearchContextData *pContext = nil;
sSearchConfig *aSearchConfig = nil;
AuthorizationRef authRef = 0;
AuthorizationItemSet* resultRightSet = NULL;
try
{
if ( inData == nil ) throw( (sInt32)eDSNullParameter );
if ( inData->fInRequestData == nil ) throw( (sInt32)eDSNullDataBuff );
if ( inData->fInRequestData->fBufferData == nil ) throw( (sInt32)eDSEmptyBuffer );
pContext = (sSearchContextData *)gSNNodeRef->GetItemData( inData->fInNodeRef );
if ( pContext == nil ) throw( (sInt32)eDSInvalidNodeRef );
if (pContext->fSearchConfigKey == eDSNetworkSearchNodeName) throw( (sInt32)eDSInvalidNodeRef );
fMutex.Wait();
aSearchConfig = FindSearchConfigWithKey(pContext->fSearchConfigKey);
if ( aSearchConfig == nil ) throw( (sInt32)eDSInvalidNodeRef );
if ( aSearchConfig->fSearchNodeList == nil ) throw( (sInt32)eSearchPathNotDefined );
aRequest = inData->fInRequestCode;
bufLen = inData->fInRequestData->fBufferLength;
if ( bufLen < sizeof( AuthorizationExternalForm ) ) throw( (sInt32)eDSInvalidBuffFormat );
siResult = AuthorizationCreateFromExternalForm((AuthorizationExternalForm *)inData->fInRequestData->fBufferData,
&authRef);
if (siResult != errAuthorizationSuccess)
{
throw( (sInt32)eDSPermissionError );
}
AuthorizationItem rights[] = { {"system.services.directory.configure", 0, 0, 0} };
AuthorizationItemSet rightSet = { sizeof(rights)/ sizeof(*rights), rights };
siResult = AuthorizationCopyRights(authRef, &rightSet, NULL,
kAuthorizationFlagExtendRights, &resultRightSet);
if (resultRightSet != NULL)
{
AuthorizationFreeItemSet(resultRightSet);
resultRightSet = NULL;
}
if (siResult != errAuthorizationSuccess)
{
throw( (sInt32)eDSPermissionError );
}
switch( aRequest )
{
case 111:
SwitchSearchPolicy( kNetInfoSearchPolicy, aSearchConfig );
if (aSearchConfig->pConfigFromXML)
{
siResult = aSearchConfig->pConfigFromXML->SetSearchPolicy(kNetInfoSearchPolicy);
siResult = aSearchConfig->pConfigFromXML->WriteConfig();
}
break;
case 222:
SwitchSearchPolicy( kLocalSearchPolicy, aSearchConfig );
if (aSearchConfig->pConfigFromXML)
{
siResult = aSearchConfig->pConfigFromXML->SetSearchPolicy(kLocalSearchPolicy);
siResult = aSearchConfig->pConfigFromXML->WriteConfig();
}
break;
case 333:
SwitchSearchPolicy( kCustomSearchPolicy, aSearchConfig );
if (aSearchConfig->pConfigFromXML)
{
siResult = aSearchConfig->pConfigFromXML->SetSearchPolicy(kCustomSearchPolicy);
siResult = aSearchConfig->pConfigFromXML->WriteConfig();
}
break;
case 444:
xmlDataLength = (sInt32) bufLen - sizeof( AuthorizationExternalForm );
if ( xmlDataLength <= 0 ) throw( (sInt32)eDSInvalidBuffFormat );
xmlData = CFDataCreate(NULL,(UInt8 *)(inData->fInRequestData->fBufferData + sizeof( AuthorizationExternalForm )),xmlDataLength);
cspArray = (CFMutableArrayRef)CFPropertyListCreateFromXMLData(NULL,xmlData,0,NULL);
if (aSearchConfig->pConfigFromXML)
{
siResult = aSearchConfig->pConfigFromXML->SetListArray(cspArray);
siResult = aSearchConfig->pConfigFromXML->WriteConfig();
}
CFRelease(cspArray);
CFRelease(xmlData);
SwitchSearchPolicy( kCustomSearchPolicy, aSearchConfig );
break;
case 555:
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 ( aSearchConfig->pConfigFromXML != nil)
{
dhcpLDAPdict = aSearchConfig->pConfigFromXML->GetDHCPLDAPDictionary();
if (dhcpLDAPdict != 0)
{
xmlData = CFPropertyListCreateXMLData(NULL,dhcpLDAPdict);
}
if (xmlData != 0)
{
*(CFIndex*)(inData->fOutRequestResponse->fBufferData) = CFDataGetLength(xmlData);
inData->fOutRequestResponse->fBufferLength = sizeof( CFIndex );
CFRelease(xmlData);
xmlData = 0;
}
else
{
*(CFIndex*)(inData->fOutRequestResponse->fBufferData) = 0;
inData->fOutRequestResponse->fBufferLength = sizeof( CFIndex );
}
}
break;
case 556:
CFRange aRange;
if ( inData->fOutRequestResponse == nil ) throw( (sInt32)eDSNullDataBuff );
if ( inData->fOutRequestResponse->fBufferData == nil ) throw( (sInt32)eDSEmptyBuffer );
if ( aSearchConfig->pConfigFromXML != nil )
{
dhcpLDAPdict = aSearchConfig->pConfigFromXML->GetDHCPLDAPDictionary();
if (dhcpLDAPdict != 0)
{
xmlData = CFPropertyListCreateXMLData(NULL,dhcpLDAPdict);
}
if (xmlData != 0)
{
aRange.location = 0;
aRange.length = CFDataGetLength(xmlData);
if ( inData->fOutRequestResponse->fBufferSize < (unsigned int)aRange.length ) throw( (sInt32)eDSBufferTooSmall );
CFDataGetBytes( xmlData, aRange, (UInt8*)(inData->fOutRequestResponse->fBufferData) );
inData->fOutRequestResponse->fBufferLength = aRange.length;
CFRelease(xmlData);
xmlData = 0;
}
}
break;
case 557:
xmlDataLength = (sInt32) bufLen - sizeof( AuthorizationExternalForm );
if ( xmlDataLength <= 0 ) throw( (sInt32)eDSInvalidBuffFormat );
xmlData = CFDataCreate(NULL,(UInt8 *)(inData->fInRequestData->fBufferData + sizeof( AuthorizationExternalForm )),xmlDataLength);
dhcpLDAPdict = (CFDictionaryRef)CFPropertyListCreateFromXMLData(NULL,xmlData,0,NULL);
if (aSearchConfig->pConfigFromXML)
{
aSearchConfig->pConfigFromXML->SetDHCPLDAPDictionary(dhcpLDAPdict);
siResult = aSearchConfig->pConfigFromXML->WriteConfig();
}
CFRelease(dhcpLDAPdict);
CFRelease(xmlData);
if (aSearchConfig->fSearchConfigKey == kNetInfoSearchPolicy)
{
SwitchSearchPolicy( aSearchConfig->fSearchConfigKey, aSearchConfig );
}
break;
default:
break;
}
fMutex.Signal();
}
catch( sInt32 err )
{
fMutex.Signal();
siResult = err;
}
if (authRef != 0)
{
AuthorizationFree(authRef, 0);
authRef = 0;
}
return( siResult );
}
sInt32 CSearchNode:: CleanSearchConfigData ( sSearchConfig *inList )
{
sInt32 siResult = eDSNoErr;
if ( inList != nil )
{
inList->fSearchPolicy = 0;
inList->fSearchConfigKey = 0;
inList->fDirNodeType = kUnknownNodeType;
inList->fNext = nil;
if (inList->fSearchNodeName != nil)
{
free(inList->fSearchNodeName);
inList->fSearchNodeName = nil;
}
if (inList->fSearchConfigFilePrefix != nil)
{
free(inList->fSearchConfigFilePrefix);
inList->fSearchConfigFilePrefix = nil;
}
CleanSearchListData( inList->fSearchNodeList );
inList->fSearchNodeList = nil;
if (inList->pConfigFromXML != nil)
{
delete(inList->pConfigFromXML);
inList->pConfigFromXML = nil;
}
}
return( siResult );
}
sInt32 CSearchNode:: CleanSearchListData ( sSearchList *inList )
{
sInt32 siResult = eDSNoErr;
sSearchList *pList = nil;
sSearchList *pDeleteList = nil;
if (inList != nil)
{
pList = inList;
while (pList != nil)
{
pDeleteList = pList;
pList = pList->fNext; if (pDeleteList->fNodeName != nil)
{
delete ( pDeleteList->fNodeName );
}
pDeleteList->fOpened = false;
if (pDeleteList->fNodeRef != 0)
{
::dsCloseDirNode(pDeleteList->fNodeRef); pDeleteList->fNodeRef = 0;
}
pDeleteList->fNext = nil;
if (pDeleteList->fDataList != nil)
{
dsDataListDeallocatePriv ( pDeleteList->fDataList );
free( pDeleteList->fDataList );
pDeleteList->fDataList = nil;
}
delete( pDeleteList );
pDeleteList = nil;
}
}
return( siResult );
}
sSearchConfig *CSearchNode::MakeSearchConfigData ( sSearchList *inSearchNodeList,
uInt32 inSearchPolicy,
CConfigs *inConfigFromXML,
char *inSearchNodeName,
char *inSearchConfigFilePrefix,
eDirNodeType inDirNodeType,
uInt32 inSearchConfigType )
{
sInt32 siResult = eDSNoErr;
sSearchConfig *configOut = nil;
configOut = (sSearchConfig *) ::calloc(sizeof(sSearchConfig), sizeof(char));
if (configOut != nil)
{
siResult = CleanSearchConfigData(configOut);
configOut->fSearchNodeList = inSearchNodeList;
configOut->fSearchPolicy = inSearchPolicy;
configOut->pConfigFromXML = inConfigFromXML;
configOut->fSearchNodeName = inSearchNodeName;
configOut->fSearchConfigFilePrefix = inSearchConfigFilePrefix;
configOut->fDirNodeType = inDirNodeType;
configOut->fSearchConfigKey = inSearchConfigType;
configOut->fNext = nil;
}
return( configOut );
}
sSearchConfig *CSearchNode:: FindSearchConfigWithKey ( uInt32 inSearchConfigKey )
{
sSearchConfig *configOut = nil;
fMutex.Wait();
configOut = pSearchConfigList;
while ( configOut != nil )
{
if (configOut->fSearchConfigKey == inSearchConfigKey)
{
break;
}
configOut = configOut->fNext;
}
fMutex.Signal();
return( configOut );
}
sInt32 CSearchNode:: AddSearchConfigToList ( sSearchConfig *inSearchConfig )
{
sSearchConfig *aConfigList = nil;
sInt32 siResult = eDSInvalidIndex;
bool uiDup = false;
fMutex.Wait();
aConfigList = pSearchConfigList;
while ( aConfigList != nil ) {
if (aConfigList->fSearchConfigKey == inSearchConfig->fSearchConfigKey)
{
uiDup = true;
break;
}
aConfigList = aConfigList->fNext;
}
if (!uiDup) {
aConfigList = pSearchConfigList;
if (aConfigList == nil)
{
pSearchConfigList = inSearchConfig;
}
else
{
while ( aConfigList->fNext != nil )
{
aConfigList = aConfigList->fNext;
}
aConfigList->fNext = inSearchConfig;
}
siResult = eDSNoErr;
}
fMutex.Signal();
return( siResult );
}
sInt32 CSearchNode::CloseAttributeList ( sCloseAttributeList *inData )
{
sInt32 siResult = eDSNoErr;
sSearchContextData *pContext = nil;
pContext = (sSearchContextData *)gSNNodeRef->GetItemData( inData->fInAttributeListRef );
if ( pContext != nil )
{
gSNNodeRef->RemoveItem( inData->fInAttributeListRef );
}
else
{
siResult = eDSInvalidAttrListRef;
}
return( siResult );
}
sInt32 CSearchNode::CloseAttributeValueList ( sCloseAttributeValueList *inData )
{
sInt32 siResult = eDSNoErr;
sSearchContextData *pContext = nil;
pContext = (sSearchContextData *)gSNNodeRef->GetItemData( inData->fInAttributeValueListRef );
if ( pContext != nil )
{
gSNNodeRef->RemoveItem( inData->fInAttributeValueListRef );
}
else
{
siResult = eDSInvalidAttrValueRef;
}
return( siResult );
}
sSearchList *CSearchNode::DupSearchListWithNewRefs ( sSearchList *inSearchList )
{
sSearchList *outSearchList = nil;
sSearchList *pSearchList = inSearchList;
sSearchList *aSearchList = nil;
sSearchList *tailSearchList = nil;
bool isFirst = true;
bool getLocalFirst = true;
while (pSearchList != nil)
{
aSearchList = (sSearchList *)::calloc( 1, sizeof( sSearchList ) );
aSearchList->fOpened = false;
aSearchList->fNodeRef = 0;
aSearchList->fNodeName = nil;
aSearchList->fDataList = nil;
aSearchList->fNext = nil;
if (isFirst)
{
outSearchList = aSearchList;
tailSearchList = aSearchList;
isFirst = false;
}
else
{
tailSearchList->fNext = aSearchList;
tailSearchList = aSearchList;
}
if (pSearchList->fNodeName != nil)
{
aSearchList->fNodeName = (char *)::calloc(1, ::strlen(pSearchList->fNodeName) + 1);
::strcpy(aSearchList->fNodeName,pSearchList->fNodeName);
if (getLocalFirst)
{
aSearchList->fDataList = ::dsBuildFromPathPriv( kstrDefaultLocalNodeName, "/" );
getLocalFirst = false;
}
else
{
aSearchList->fDataList = ::dsBuildFromPathPriv( aSearchList->fNodeName, "/" );
}
}
pSearchList = pSearchList->fNext;
}
return( outSearchList );
}
void CSearchNode::ContinueDeallocProc ( void* inContinueData )
{
sSearchContinueData *pContinue = (sSearchContinueData *)inContinueData;
if ( pContinue != nil )
{
if ( pContinue->fAliasList != nil )
{
::dsDataListDeallocatePriv( pContinue->fAliasList );
free( pContinue->fAliasList );
pContinue->fAliasList = nil;
}
if ( pContinue->fAliasAttribute != nil )
{
::dsDataListDeallocatePriv( pContinue->fAliasAttribute );
free( pContinue->fAliasAttribute );
pContinue->fAliasAttribute = nil;
}
if ( pContinue->fDataBuff != nil )
{
::dsDataBufferDeallocatePriv( pContinue->fDataBuff );
pContinue->fDataBuff = nil;
}
if ( pContinue->fContextData != nil )
{
::dsReleaseContinueData( pContinue->fNodeRef, pContinue->fContextData );
pContinue->fContextData = nil;
}
free( pContinue );
pContinue = nil;
}
}
void CSearchNode::ContextDeallocProc ( void* inContextData )
{
sSearchContextData *pContext = (sSearchContextData *) inContextData;
if ( pContext != nil )
{
CleanContextData( pContext );
}
}
void CSearchNode:: ContextSetListChangedProc ( void* inContextData )
{
sSearchContextData *pContext = (sSearchContextData *) inContextData;
if ( pContext != nil )
{
if ( pContext->pSearchListMutex != nil ) {
pContext->pSearchListMutex->Wait();
pContext->bListChanged = true;
pContext->pSearchListMutex->Signal();
}
}
}
void CSearchNode:: SetSearchPolicyIndicatorFile ( uInt32 inSearchNodeKey, uInt32 inSearchPolicyIndex )
{
sInt32 siResult = eDSNoErr;
struct stat statResult;
if (inSearchNodeKey == eDSAuthenticationSearchNodeName)
{
siResult = ::stat( "/Library/Preferences/DirectoryService", &statResult );
if (siResult != eDSNoErr)
{
siResult = ::stat( "/Library/Preferences", &statResult );
if (siResult != eDSNoErr)
{
::mkdir( "/Library/Preferences", 0775 );
::chmod( "/Library/Preferences", 0775 ); }
siResult = ::stat( "/Library/Preferences/DirectoryService", &statResult );
if (siResult != eDSNoErr)
{
::mkdir( "/Library/Preferences/DirectoryService", 0775 );
::chmod( "/Library/Preferences/DirectoryService", 0775 ); }
}
RemoveSearchPolicyIndicatorFile();
if (inSearchPolicyIndex == 3)
{
system( "touch /Library/Preferences/DirectoryService/.DSRunningSP3" );
}
else if (inSearchPolicyIndex == 2)
{
system( "touch /Library/Preferences/DirectoryService/.DSRunningSP2" );
}
else {
system( "touch /Library/Preferences/DirectoryService/.DSRunningSP1" );
}
}
}
void CSearchNode:: RemoveSearchPolicyIndicatorFile ( void )
{
sInt32 siResult = eDSNoErr;
struct stat statResult;
siResult = ::stat( "/Library/Preferences/DirectoryService/.DSRunningSP1", &statResult );
if (siResult == eDSNoErr)
{
system( "rm -f /Library/Preferences/DirectoryService/.DSRunningSP1" );
}
siResult = ::stat( "/Library/Preferences/DirectoryService/.DSRunningSP2", &statResult );
if (siResult == eDSNoErr)
{
system( "rm -f /Library/Preferences/DirectoryService/.DSRunningSP2" );
}
siResult = ::stat( "/Library/Preferences/DirectoryService/.DSRunningSP3", &statResult );
if (siResult == eDSNoErr)
{
system( "rm -f /Library/Preferences/DirectoryService/.DSRunningSP3" );
}
}
sSearchList *CSearchNode::BuildNetworkNodeList ( void )
{
sSearchList *outSearchList = nil;
sSearchList *aSearchList = nil;
sSearchList *tailSearchList = nil;
bool isFirst = true;
tDataBuffer *pNodeBuff = nil;
bool done = false;
unsigned long uiCount = 0;
unsigned long uiIndex = 0;
tContextData context = NULL;
tDataList *pDataList = nil;
sInt32 siResult = eDSNoErr;
try
{
pNodeBuff = ::dsDataBufferAllocatePriv( 2048 );
if ( pNodeBuff == nil ) throw( (sInt32)eMemoryAllocError );
while ( done == false )
{
do
{
siResult = dsFindDirNodes( fDirRef, pNodeBuff, NULL, eDSDefaultNetworkNodes, &uiCount, &context );
if (siResult == eDSBufferTooSmall)
{
uInt32 bufSize = pNodeBuff->fBufferSize;
dsDataBufferDeallocatePriv( pNodeBuff );
pNodeBuff = nil;
pNodeBuff = ::dsDataBufferAllocatePriv( bufSize * 2 );
}
} while (siResult == eDSBufferTooSmall);
if ( siResult != eDSNoErr ) throw( siResult );
for ( uiIndex = 1; uiIndex <= uiCount; uiIndex++ )
{
siResult = dsGetDirNodeName( fDirRef, pNodeBuff, uiIndex, &pDataList );
if ( siResult != eDSNoErr ) throw( siResult );
aSearchList = (sSearchList *)::calloc( 1, sizeof( sSearchList ) );
if ( aSearchList == nil ) throw( (sInt32)eMemoryAllocError );
aSearchList->fOpened = false;
aSearchList->fNodeRef = 0;
aSearchList->fDataList = pDataList;
aSearchList->fNodeName = dsGetPathFromListPriv( pDataList, "/" );
aSearchList->fNext = nil;
if (isFirst)
{
outSearchList = aSearchList;
tailSearchList = aSearchList;
isFirst = false;
}
else
{
tailSearchList->fNext = aSearchList;
tailSearchList = aSearchList;
}
pDataList = nil;
}
done = (context == nil);
}
dsDataBufferDeallocatePriv( pNodeBuff );
pNodeBuff = nil;
}
catch( sInt32 err )
{
outSearchList = nil;
CShared::LogIt( 0x0F, "Memory error finding the Default Network Nodes with error: %l", err );
}
return( outSearchList );
}