#include <stdio.h>
#include "DSUtils.h"
DSUtils::DSUtils()
{
mDSRef = 0;
mNodeRef = 0;
mNodeListBuff = NULL;
mNodeCount = 0;
mCurrentNodeAuthenticated = false;
mCurrentNodeIsLDAP = false;
}
DSUtils::~DSUtils()
{
if ( mNodeListBuff != NULL )
{
dsDataBufferDeAllocate( mDSRef, mNodeListBuff );
mNodeListBuff = NULL;
}
this->CloseCurrentNodeRef();
if ( mDSRef != 0 )
{
dsCloseDirService( mDSRef );
mDSRef = 0;
}
}
void
DSUtils::CloseCurrentNodeRef( void )
{
if ( mNodeRef != 0 )
{
dsCloseDirNode( mNodeRef );
mNodeRef = 0;
mCurrentNodeAuthenticated = false;
mCurrentNodeIsLDAP = false;
}
}
tDirStatus
DSUtils::OpenDirectoryServices( void )
{
tDirStatus status = eDSNoErr;
if ( mDSRef == 0 )
status = dsOpenDirService( &mDSRef );
return status;
}
tDirStatus
DSUtils::OpenSpecificPasswordServerNode( const char *inServerAddress )
{
char pwServerNodeStr[256];
tDataList *pDataList = nil;
tDirStatus status = eDSNoErr;
if ( inServerAddress == NULL )
return eParameterError;
status = this->OpenDirectoryServices();
if ( status != eDSNoErr )
return status;
this->CloseCurrentNodeRef();
strcpy( pwServerNodeStr, "/PasswordServer/only/" );
strcat( pwServerNodeStr, inServerAddress );
pDataList = dsBuildFromPath( mDSRef, pwServerNodeStr, "/" );
status = dsOpenDirNode( mDSRef, pDataList, &mNodeRef );
dsDataListDeallocate( mDSRef, pDataList );
free( pDataList );
return status;
}
tDirStatus
DSUtils::OpenLocalLDAPNode( const char *inUser, const char *inPassword )
{
tDirStatus status = eDSNoErr;
tContextData context = NULL;
tDataListPtr patternList = NULL;
tDataBufferPtr authBuff = NULL;
tDataBufferPtr authStepBuff = NULL;
tContextData continueData = NULL;
tDataNodePtr typeBuff = NULL;
long len = 0;
if ( mCurrentNodeIsLDAP && mCurrentNodeAuthenticated )
return eDSNoErr;
status = this->OpenDirectoryServices();
if ( status != eDSNoErr )
return status;
if ( mNodeListBuff == NULL )
{
mNodeListBuff = dsDataBufferAllocate( mDSRef, 4096 );
if ( mNodeListBuff == NULL )
return eMemoryError;
}
else
{
mNodeListBuff->fBufferLength = 0;
}
patternList = dsBuildFromPath( mDSRef, "/LDAPv3/127.0.0.1", "/" );
if ( patternList == NULL )
return eMemoryError;
status = dsFindDirNodes( mDSRef, mNodeListBuff, patternList, eDSExact, &mNodeCount, &context );
if ( status != eDSNoErr )
return status;
if ( mNodeCount < 1 )
return eDSNodeNotFound;
status = this->OpenLocallyHostedNode( 1 );
if ( status != eDSNoErr )
return status;
mCurrentNodeIsLDAP = true;
if ( inUser != NULL && inPassword != NULL )
{
authBuff = dsDataBufferAllocate( mDSRef, 4096 );
if ( authBuff == NULL )
return eMemoryError;
authStepBuff = dsDataBufferAllocate( mDSRef, 2048 );
if ( authStepBuff == NULL )
return eMemoryError;
typeBuff = dsDataNodeAllocateString( mDSRef, kDSStdAuthNodeNativeClearTextOK );
if ( typeBuff == NULL )
return eMemoryError;
len = strlen( inUser );
memcpy( authBuff->fBufferData, &len, 4 );
strcpy( authBuff->fBufferData + 4, inUser );
authBuff->fBufferLength = 4 + len;
len = strlen( inPassword );
memcpy( authBuff->fBufferData + authBuff->fBufferLength, &len, 4 );
strcpy( authBuff->fBufferData + authBuff->fBufferLength + 4, inPassword );
authBuff->fBufferLength += 4 + len;
status = dsDoDirNodeAuth( this->GetCurrentNodeRef(), typeBuff, false, authBuff, authStepBuff, &continueData );
if ( status == eDSNoErr )
mCurrentNodeAuthenticated = true;
}
return status;
}
tDirStatus
DSUtils::OpenNodeByName( const char *inNodeName, const char *inUser, const char *inPassword )
{
tDirStatus status = eDSNoErr;
tDataListPtr nodeName = NULL;
tDataBufferPtr authBuff = NULL;
tDataBufferPtr authStepBuff = NULL;
tContextData continueData = NULL;
tDataNodePtr typeBuff = NULL;
long len = 0;
if ( inNodeName == NULL )
return eParameterError;
status = this->OpenDirectoryServices();
if ( status != eDSNoErr )
return status;
if ( mNodeListBuff == NULL )
{
mNodeListBuff = dsDataBufferAllocate( mDSRef, 4096 );
if ( mNodeListBuff == NULL )
return eMemoryError;
}
else
{
mNodeListBuff->fBufferLength = 0;
}
nodeName = dsBuildFromPath( mDSRef, inNodeName, "/" );
if ( nodeName == NULL )
return eMemoryError;
status = dsOpenDirNode( mDSRef, nodeName, &mNodeRef );
dsDataListDeallocate( mDSRef, nodeName );
free( nodeName );
if ( status != eDSNoErr )
return status;
if ( inUser != NULL && inPassword != NULL )
{
authBuff = dsDataBufferAllocate( mDSRef, 4096 );
if ( authBuff == NULL )
return eMemoryError;
authStepBuff = dsDataBufferAllocate( mDSRef, 2048 );
if ( authStepBuff == NULL )
return eMemoryError;
typeBuff = dsDataNodeAllocateString( mDSRef, kDSStdAuthNodeNativeClearTextOK );
if ( typeBuff == NULL )
return eMemoryError;
len = strlen( inUser );
memcpy( authBuff->fBufferData, &len, 4 );
strcpy( authBuff->fBufferData + 4, inUser );
authBuff->fBufferLength = 4 + len;
len = strlen( inPassword );
memcpy( authBuff->fBufferData + authBuff->fBufferLength, &len, 4 );
strcpy( authBuff->fBufferData + authBuff->fBufferLength + 4, inPassword );
authBuff->fBufferLength += 4 + len;
status = dsDoDirNodeAuth( this->GetCurrentNodeRef(), typeBuff, false, authBuff, authStepBuff, &continueData );
if ( status == eDSNoErr )
mCurrentNodeAuthenticated = true;
}
return status;
}
tDirStatus
DSUtils::OpenNetInfoParentNode( void )
{
tDirStatus status = eDSNoErr;
tDataList *pDataList = NULL;
status = this->OpenDirectoryServices();
if ( status != eDSNoErr )
return status;
if ( mNodeListBuff == NULL )
{
mNodeListBuff = dsDataBufferAllocate( mDSRef, 4096 );
if ( mNodeListBuff == NULL )
return eMemoryError;
}
else
{
mNodeListBuff->fBufferLength = 0;
}
pDataList = dsBuildFromPath( mDSRef, "/NetInfo/..", "/" );
status = dsOpenDirNode( mDSRef, pDataList, &mNodeRef );
dsDataListDeallocate( mDSRef, pDataList );
free( pDataList );
return status;
}
tDirStatus
DSUtils::GetLocallyHostedNodeList( void )
{
tDirStatus status = eDSNoErr;
tContextData context = NULL;
status = this->OpenDirectoryServices();
if ( status != eDSNoErr )
return status;
if ( mNodeListBuff == NULL )
{
mNodeListBuff = dsDataBufferAllocate( mDSRef, 4096 );
if ( mNodeListBuff == NULL )
return eMemoryError;
}
status = dsFindDirNodes( mDSRef, mNodeListBuff, NULL, eDSLocalHostedNodes, &mNodeCount, &context );
if ( status != eDSNoErr )
return status;
if ( mNodeCount < 1 )
status = eDSNodeNotFound;
return status;
}
tDirStatus
DSUtils::OpenLocallyHostedNode( unsigned long inNodeIndex )
{
tDirStatus status = eDSNoErr;
tDataList *nodeName = NULL;
if ( mDSRef == 0 || mNodeListBuff == NULL || inNodeIndex > mNodeCount )
return eParameterError;
this->CloseCurrentNodeRef();
status = dsGetDirNodeName( mDSRef, mNodeListBuff, inNodeIndex, &nodeName );
if ( status != eDSNoErr )
return status;
status = dsOpenDirNode( mDSRef, nodeName, &mNodeRef );
dsDataListDeallocate( mDSRef, nodeName );
free( nodeName );
return status;
}
tDirStatus
DSUtils::OpenRecord(
const char *inRecordType,
const char *inRecordName,
tRecordReference *outRecordRef,
bool inCreate )
{
tDirStatus status = eDSNoErr;
tDataNodePtr recordTypeNode = NULL;
tDataNodePtr recordNameNode = NULL;
if ( mDSRef == 0 || mNodeRef == 0 || inRecordType == NULL || inRecordName == NULL || outRecordRef == NULL )
return eParameterError;
recordTypeNode = dsDataNodeAllocateString( mDSRef, inRecordType );
recordNameNode = dsDataNodeAllocateString( mDSRef, inRecordName );
status = dsOpenRecord( mNodeRef, recordTypeNode, recordNameNode, outRecordRef );
if ( inCreate && status == eDSRecordNotFound )
status = dsCreateRecordAndOpen( mNodeRef, recordTypeNode, recordNameNode, outRecordRef );
if ( recordTypeNode ) {
dsDataNodeDeAllocate( mDSRef, recordTypeNode );
recordTypeNode = NULL;
}
if ( recordNameNode ) {
dsDataNodeDeAllocate( mDSRef, recordNameNode );
recordNameNode = NULL;
}
return status;
}
tDirStatus
DSUtils::DoActionOnCurrentNode( void )
{
fprintf( stderr, "warning: DSUtils::DoActionOnCurrentNode() called, does not perform any action." );
return (tDirStatus)0;
}
tDirStatus
DSUtils::DoActionForAllLocalNodes( void )
{
tDirStatus status = eDSNoErr;
tDirStatus status1 = eDSNoErr;
unsigned long index = 0;
unsigned long nodeCount = 0;
status = this->GetLocallyHostedNodeList();
if ( status != eDSNoErr )
return status;
nodeCount = this->GetLocallyHostedNodeCount();
for ( index = 1; index <= nodeCount; index++ )
{
status1 = this->OpenLocallyHostedNode( index );
if ( status1 != eDSNoErr )
{
if ( status == eDSNoErr )
status = status1;
continue;
}
status1 = this->DoActionOnCurrentNode();
if ( status1 != eDSNoErr && status == eDSNoErr )
status = status1;
}
return status;
}
tDirStatus
DSUtils::FillAuthBuff( tDataBuffer *inAuthBuff, unsigned long inCount, unsigned long inLen, ... )
{
tDirStatus error = eDSNoErr;
unsigned long curr = 0;
unsigned long buffSize = 0;
unsigned long count = inCount;
unsigned long len = inLen;
const void *data = NULL;
bool firstPass = true;
char *p = nil;
va_list args;
if ( inAuthBuff == nil )
return eParameterError;
if ( inAuthBuff->fBufferData == nil )
{
return( eDSEmptyBuffer );
}
p = inAuthBuff->fBufferData;
buffSize = inAuthBuff->fBufferSize;
va_start( args, inLen );
data = va_arg( args, void * );
while ( count-- > 0 )
{
if ( !firstPass )
{
len = va_arg( args, unsigned long );
data = va_arg( args, void * );
}
if ( (curr + len) > buffSize )
{
return( eDSBufferTooSmall );
}
::memcpy( &(p[ curr ]), &len, sizeof( long ) );
curr += sizeof( long );
if ( len > 0 )
{
memcpy( &(p[ curr ]), data, len );
curr += len;
}
firstPass = false;
}
inAuthBuff->fBufferLength = curr;
return( error );
}
tDirStatus
DSUtils::GetServerAddressForUser( const char *uname, char *serverAddress, char **userNodeName )
{
tDataBuffer *tDataBuff = NULL;
tDirNodeReference nodeRef = 0;
tDirStatus status = eDSNoErr;
tContextData context = NULL;
unsigned long nodeCount = 0;
unsigned long attrIndex = 0;
tDataList *nodeName = NULL;
tAttributeEntryPtr pAttrEntry = NULL;
tDataList *pRecName = NULL;
tDataList *pRecType = NULL;
tDataList *pAttrType = NULL;
unsigned long recCount = 0;
tRecordEntry *pRecEntry = NULL;
tAttributeListRef attrListRef = 0;
char *pUserLocation = NULL;
tAttributeValueListRef valueRef = 0;
tAttributeValueEntry *pValueEntry = NULL;
tDataList *pUserNode = NULL;
tDirNodeReference userNodeRef = 0;
if ( uname == NULL )
return eDSAuthUnknownUser;
if ( userNodeName != NULL )
*userNodeName = NULL;
try
{
status = this->OpenDirectoryServices();
if ( status != eDSNoErr )
throw( status );
tDataBuff = dsDataBufferAllocate( mDSRef, 4096 );
if (tDataBuff == NULL)
throw( (tDirStatus)eMemoryError );
status = dsFindDirNodes( mDSRef, tDataBuff, NULL, eDSSearchNodeName, &nodeCount, &context );
if (status != eDSNoErr)
throw( status );
if ( nodeCount < 1 )
throw( (tDirStatus)eDSNodeNotFound );
status = dsGetDirNodeName( mDSRef, tDataBuff, 1, &nodeName );
if (status != eDSNoErr)
throw( status );
status = dsOpenDirNode( mDSRef, nodeName, &nodeRef );
dsDataListDeallocate( mDSRef, nodeName );
free( nodeName );
nodeName = NULL;
if (status != eDSNoErr)
throw( status );
pRecName = dsBuildListFromStrings( mDSRef, uname, NULL );
pRecType = dsBuildListFromStrings( mDSRef, kDSStdRecordTypeUsers, NULL );
pAttrType = dsBuildListFromStrings( mDSRef, kDSNAttrMetaNodeLocation, NULL );
recCount = 1;
status = dsGetRecordList( nodeRef, tDataBuff, pRecName, eDSExact, pRecType, pAttrType, 0, &recCount, &context );
if ( status != eDSNoErr )
throw( status );
if ( recCount == 0 )
throw( (tDirStatus)eDSAuthUnknownUser );
status = dsGetRecordEntry( nodeRef, tDataBuff, 1, &attrListRef, &pRecEntry );
if ( status != eDSNoErr )
throw( status );
for ( attrIndex = 1; (attrIndex <= pRecEntry->fRecordAttributeCount) && (status == eDSNoErr); attrIndex++ )
{
status = dsGetAttributeEntry( nodeRef, tDataBuff, attrListRef, attrIndex, &valueRef, &pAttrEntry );
if ( status == eDSNoErr && pAttrEntry != NULL )
{
if ( strcmp( pAttrEntry->fAttributeSignature.fBufferData, kDSNAttrMetaNodeLocation ) == 0 )
{
status = dsGetAttributeValue( nodeRef, tDataBuff, 1, valueRef, &pValueEntry );
if ( status == eDSNoErr && pValueEntry != NULL )
{
pUserLocation = (char *) calloc( pValueEntry->fAttributeValueData.fBufferLength + 1, sizeof(char) );
memcpy( pUserLocation, pValueEntry->fAttributeValueData.fBufferData, pValueEntry->fAttributeValueData.fBufferLength );
}
}
if ( pValueEntry != NULL )
dsDeallocAttributeValueEntry( mDSRef, pValueEntry );
pValueEntry = NULL;
dsDeallocAttributeEntry( mDSRef, pAttrEntry );
pAttrEntry = NULL;
dsCloseAttributeValueList( valueRef );
valueRef = 0;
}
}
dsCloseAttributeList( attrListRef );
attrListRef = 0;
dsDeallocRecordEntry( mDSRef, pRecEntry );
pRecEntry = NULL;
if ( pUserLocation == NULL )
throw( (tDirStatus)eDSAuthUnknownUser );
pUserNode = dsBuildFromPath( mDSRef, pUserLocation, "/" );
status = dsOpenDirNode( mDSRef, pUserNode, &userNodeRef );
if ( status != eDSNoErr )
throw( status );
if ( userNodeName != NULL )
*userNodeName = pUserLocation;
if (pRecName != NULL) {
dsDataListDeallocate( mDSRef, pRecName );
free( pRecName );
pRecName = NULL;
}
if (pRecType != NULL) {
dsDataListDeallocate( mDSRef, pRecType );
free( pRecType );
pRecType = NULL;
}
if (pAttrType != NULL) {
dsDataListDeallocate( mDSRef, pAttrType );
free( pAttrType );
pAttrType = NULL;
}
pRecName = dsBuildListFromStrings( mDSRef, "passwordserver", NULL );
pRecType = dsBuildListFromStrings( mDSRef, kDSStdRecordTypeConfig, NULL );
pAttrType = dsBuildListFromStrings( mDSRef, kDS1AttrPasswordServerLocation, NULL );
recCount = 1;
status = dsGetRecordList( nodeRef, tDataBuff, pRecName, eDSExact, pRecType, pAttrType, 0, &recCount, &context );
if ( status != eDSNoErr )
throw( status );
if ( recCount == 0 )
throw( (tDirStatus)eDSRecordNotFound );
status = dsGetRecordEntry( nodeRef, tDataBuff, 1, &attrListRef, &pRecEntry );
if ( status != eDSNoErr )
throw( status );
for ( attrIndex = 1; (attrIndex <= pRecEntry->fRecordAttributeCount) && (status == eDSNoErr); attrIndex++ )
{
status = dsGetAttributeEntry( nodeRef, tDataBuff, attrListRef, attrIndex, &valueRef, &pAttrEntry );
if ( status == eDSNoErr && pAttrEntry != NULL )
{
if ( strcmp( pAttrEntry->fAttributeSignature.fBufferData, kDS1AttrPasswordServerLocation ) == 0 )
{
status = dsGetAttributeValue( nodeRef, tDataBuff, 1, valueRef, &pValueEntry );
if ( status == eDSNoErr && pValueEntry != NULL )
{
memcpy( serverAddress, pValueEntry->fAttributeValueData.fBufferData, pValueEntry->fAttributeValueData.fBufferLength );
serverAddress[pValueEntry->fAttributeValueData.fBufferLength] = '\0';
}
}
if ( pValueEntry != NULL )
dsDeallocAttributeValueEntry( mDSRef, pValueEntry );
pValueEntry = NULL;
dsDeallocAttributeEntry( mDSRef, pAttrEntry );
pAttrEntry = NULL;
dsCloseAttributeValueList( valueRef );
valueRef = 0;
}
}
}
catch ( tDirStatus catchErr )
{
status = catchErr;
}
if ( attrListRef != 0 ) {
dsCloseAttributeList( attrListRef );
attrListRef = 0;
}
if ( pRecEntry != NULL ) {
dsDeallocRecordEntry( mDSRef, pRecEntry );
pRecEntry = NULL;
}
if (tDataBuff != NULL) {
bzero( tDataBuff, tDataBuff->fBufferSize );
dsDataBufferDeAllocate( mDSRef, tDataBuff );
tDataBuff = NULL;
}
if (pUserLocation != NULL && userNodeName == NULL ) {
free( pUserLocation );
pUserLocation = NULL;
}
if (pRecName != NULL) {
dsDataListDeallocate( mDSRef, pRecName );
free( pRecName );
pRecName = NULL;
}
if (pRecType != NULL) {
dsDataListDeallocate( mDSRef, pRecType );
free( pRecType );
pRecType = NULL;
}
if (pAttrType != NULL) {
dsDataListDeallocate( mDSRef, pAttrType );
free( pAttrType );
pAttrType = NULL;
}
if (nodeRef != 0) {
dsCloseDirNode(nodeRef);
nodeRef = 0;
}
return status;
}