#include <string.h> //used for strcpy, etc.
#include <stdlib.h> //used for malloc
#include <ctype.h> //use for isprint
#include <syslog.h>
#include <arpa/inet.h>
#include <spawn.h>
#include <grp.h>
#include <CommonCrypto/CommonDigest.h>
#include <Security/Authorization.h>
#include <SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h>
#include <CoreFoundation/CFPriv.h>
#include <PasswordServer/PSUtilitiesDefs.h>
#include <PasswordServer/KerberosInterface.h>
#include <PasswordServer/KerberosServiceSetup.h>
#include "DirServices.h"
#include "DirServicesUtils.h"
#include "DirServicesConst.h"
#include "DirServicesConstPriv.h"
#include "DirServicesPriv.h"
#include "LDAPv3SupportFunctions.h"
#include "CLDAPBindData.h"
#include "PrivateTypes.h"
#include "DSLDAPUtils.h"
CLDAPBindData::CLDAPBindData( tDataBufferPtr inXMLData, CFMutableDictionaryRef *outXMLDict ) :
mServer(NULL),
mServerCFString(NULL),
mSSL(false),
mLDAPv2Only(false),
mUserName(NULL),
mPassword(NULL),
mCFComputerMap(NULL),
mComputerName(NULL),
mEnetAddr(NULL)
{
UInt32 iLength = 0;
if ( outXMLDict != NULL )
*outXMLDict = NULL;
if ( inXMLData == NULL )
return;
CFMutableDictionaryRef cfXMLDict = GetXMLFromBuffer( inXMLData );
if ( cfXMLDict == NULL )
return;
*outXMLDict = cfXMLDict;
CFStringRef cfServer = (CFStringRef) CFDictionaryGetValue( cfXMLDict, CFSTR(kXMLServerKey) );
if ( cfServer != NULL && CFGetTypeID(cfServer) == CFStringGetTypeID() )
{
CFRetain( cfServer );
mServerCFString = cfServer;
iLength = (UInt32) CFStringGetMaximumSizeForEncoding( CFStringGetLength(cfServer), kCFStringEncodingUTF8) + 1;
mServer = (char *) calloc( sizeof(char), iLength );
if ( mServer != NULL )
CFStringGetCString( cfServer, mServer, iLength, kCFStringEncodingUTF8 );
}
CFBooleanRef cfBool = (CFBooleanRef) CFDictionaryGetValue( cfXMLDict, CFSTR(kXMLIsSSLFlagKey) );
if ( cfBool != NULL && CFGetTypeID(cfBool) == CFBooleanGetTypeID() )
mSSL = CFBooleanGetValue( cfBool );
CFStringRef cfUsername = (CFStringRef) CFDictionaryGetValue( cfXMLDict, CFSTR(kXMLServerAccountKey) );
if ( cfUsername != NULL && CFGetTypeID(cfUsername) == CFStringGetTypeID() && CFStringGetLength(cfUsername) != 0 )
{
iLength = (UInt32) CFStringGetMaximumSizeForEncoding( CFStringGetLength(cfUsername), kCFStringEncodingUTF8 ) + 1;
mUserName = (char *) calloc( sizeof(char), iLength );
if ( mUserName != NULL )
CFStringGetCString( cfUsername, mUserName, iLength, kCFStringEncodingUTF8 );
}
CFStringRef cfPassword = (CFStringRef) CFDictionaryGetValue( cfXMLDict, CFSTR(kXMLServerPasswordKey) );
if ( cfPassword != NULL && CFGetTypeID(cfPassword) == CFStringGetTypeID() && CFStringGetLength(cfPassword) != 0 )
{
iLength = (UInt32) CFStringGetMaximumSizeForEncoding( CFStringGetLength(cfPassword), kCFStringEncodingUTF8) + 1;
mPassword = (char *) calloc( sizeof(char), iLength );
if ( mPassword != NULL )
CFStringGetCString( cfPassword, mPassword, iLength, kCFStringEncodingUTF8 );
}
mCFComputerMap = CreateMappingFromConfig( cfXMLDict, CFSTR(kDSStdRecordTypeComputers) );
CFStringRef cfComputerName = (CFStringRef) CFDictionaryGetValue( cfXMLDict, CFSTR(kXMLUserDefinedNameKey) );
if ( cfComputerName != NULL && CFGetTypeID(cfComputerName) == CFStringGetTypeID() )
{
iLength = (UInt32)CFStringGetMaximumSizeForEncoding( CFStringGetLength(cfComputerName), kCFStringEncodingUTF8) + 1;
mComputerName = (char *) calloc( sizeof(char), iLength );
if ( mComputerName != NULL )
CFStringGetCString( cfComputerName, mComputerName, iLength, kCFStringEncodingUTF8 );
}
CFStringRef cfEnetAddr = (CFStringRef) CFDictionaryGetValue( cfXMLDict, CFSTR(kDS1AttrENetAddress) );
if ( cfEnetAddr != NULL && CFGetTypeID(cfEnetAddr) == CFStringGetTypeID() )
{
iLength = (UInt32)CFStringGetMaximumSizeForEncoding( CFStringGetLength(cfEnetAddr), kCFStringEncodingUTF8 ) + 1;
mEnetAddr = (char *)calloc( sizeof(char), iLength );
if ( mEnetAddr != NULL )
CFStringGetCString( cfEnetAddr, mEnetAddr, iLength, kCFStringEncodingUTF8 );
}
}
CLDAPBindData::~CLDAPBindData( void )
{
DSFreeString( mServer );
DSCFRelease( mServerCFString );
DSFreeString( mUserName );
DSFreePassword( mPassword );
DSCFRelease( mCFComputerMap );
DSFreeString( mComputerName );
DSFreeString( mEnetAddr );
}
tDirStatus
CLDAPBindData::DataValidForBind( void )
{
if ( mServerCFString == NULL || CFGetTypeID(mServerCFString) != CFStringGetTypeID() )
return eDSInvalidBuffFormat;
if ( mCFComputerMap == NULL )
return eDSNoStdMappingAvailable;
if ( mComputerName == NULL )
return eDSInvalidRecordName;
return eDSNoErr;
}
tDirStatus
CLDAPBindData::DataValidForRemove( void )
{
if ( mServerCFString == NULL || CFGetTypeID(mServerCFString) != CFStringGetTypeID() )
return eDSInvalidBuffFormat;
return eDSNoErr;
}
CFDictionaryRef
CLDAPBindData::CreateMappingFromConfig( CFDictionaryRef inDict, CFStringRef inRecordType )
{
CFArrayRef cfRecordMap = (CFArrayRef) CFDictionaryGetValue( inDict, CFSTR(kXMLRecordTypeMapArrayKey) );
CFMutableDictionaryRef cfReturnDict = NULL;
if ( cfRecordMap != NULL && CFGetTypeID(cfRecordMap) == CFArrayGetTypeID() )
{
CFIndex iCount = CFArrayGetCount( cfRecordMap );
CFDictionaryRef cfRecordDict = NULL;
for( CFIndex ii = 0; ii < iCount; ii++ )
{
CFDictionaryRef cfMapDict = (CFDictionaryRef) CFArrayGetValueAtIndex( cfRecordMap, ii );
if ( CFGetTypeID(cfMapDict) == CFDictionaryGetTypeID() )
{
CFStringRef cfMapName = (CFStringRef) CFDictionaryGetValue( cfMapDict, CFSTR(kXMLStdNameKey) );
if ( cfMapName != NULL && CFStringCompare( cfMapName, inRecordType, 0) == kCFCompareEqualTo )
{
cfRecordDict = cfMapDict;
break;
}
}
}
if ( cfRecordDict != NULL )
{
CFArrayRef cfNativeMap = (CFArrayRef) CFDictionaryGetValue( cfRecordDict, CFSTR(kXMLNativeMapArrayKey) );
if ( cfNativeMap != NULL && CFGetTypeID(cfNativeMap) == CFArrayGetTypeID() )
{
if ( CFArrayGetCount(cfNativeMap) > 0 )
{
cfReturnDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
CFDictionaryRef cfNativeDict = (CFDictionaryRef) CFArrayGetValueAtIndex( cfNativeMap, 0 );
if ( cfNativeDict != NULL && CFGetTypeID(cfNativeDict) == CFDictionaryGetTypeID() )
{
CFStringRef cfSearchbase = (CFStringRef) CFDictionaryGetValue( cfNativeDict, CFSTR(kXMLSearchBase) );
if ( cfSearchbase != NULL && CFGetTypeID(cfSearchbase) == CFStringGetTypeID() )
CFDictionarySetValue( cfReturnDict, CFSTR(kXMLSearchBase), cfSearchbase );
CFStringRef cfGroupStyle = (CFStringRef) CFDictionaryGetValue( cfNativeDict, CFSTR(kXMLGroupObjectClasses) );
if ( cfGroupStyle != NULL && CFGetTypeID(cfGroupStyle) == CFStringGetTypeID() )
CFDictionarySetValue( cfReturnDict, CFSTR(kXMLGroupObjectClasses), cfGroupStyle );
CFArrayRef cfObjectClasses = (CFArrayRef) CFDictionaryGetValue( cfNativeDict, CFSTR(kXMLObjectClasses) );
if ( cfObjectClasses != NULL && CFGetTypeID(cfObjectClasses) == CFArrayGetTypeID() )
CFDictionarySetValue( cfReturnDict, CFSTR(kXMLObjectClasses), cfObjectClasses );
}
}
}
CFArrayRef cfAttribMap = (CFArrayRef) CFDictionaryGetValue( cfRecordDict, CFSTR(kXMLAttrTypeMapArrayKey) );
if ( cfAttribMap != NULL && CFGetTypeID(cfAttribMap) == CFArrayGetTypeID() )
{
CFMutableDictionaryRef cfAttribDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue( cfReturnDict, CFSTR("Attributes"), cfAttribDict );
CFRelease( cfAttribDict );
iCount = CFArrayGetCount( cfAttribMap );
for( CFIndex ii = 0; ii < iCount; ii++ )
{
CFDictionaryRef cfMapDict = (CFDictionaryRef) CFArrayGetValueAtIndex( cfAttribMap, ii );
if ( cfMapDict != NULL && CFGetTypeID(cfMapDict) == CFDictionaryGetTypeID() )
{
CFStringRef cfName = (CFStringRef) CFDictionaryGetValue( cfMapDict, CFSTR(kXMLStdNameKey) );
if ( cfName != NULL && CFGetTypeID(cfName) == CFStringGetTypeID())
{
CFArrayRef cfNativeMapTemp = (CFArrayRef) CFDictionaryGetValue( cfMapDict, CFSTR(kXMLNativeMapArrayKey) );
if ( cfNativeMap != NULL && CFGetTypeID(cfNativeMapTemp) == CFArrayGetTypeID() )
{
CFDictionarySetValue( cfAttribDict, cfName, cfNativeMapTemp );
}
}
}
}
}
cfAttribMap = (CFArrayRef) CFDictionaryGetValue( inDict, CFSTR(kXMLAttrTypeMapArrayKey) );
if ( cfAttribMap != NULL && CFGetTypeID(cfAttribMap) == CFArrayGetTypeID() )
{
CFMutableDictionaryRef cfAttribDict = (CFMutableDictionaryRef) CFDictionaryGetValue( cfReturnDict, CFSTR("Attributes") );
if ( cfAttribDict == NULL )
{
cfAttribDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue( cfReturnDict, CFSTR("Attributes"), cfAttribDict );
CFRelease( cfAttribDict ); }
iCount = CFArrayGetCount( cfAttribMap );
for( CFIndex ii = 0; ii < iCount; ii++ )
{
CFDictionaryRef cfMapDict = (CFDictionaryRef) CFArrayGetValueAtIndex( cfAttribMap, ii );
if ( cfMapDict != NULL && CFGetTypeID(cfMapDict) == CFDictionaryGetTypeID() )
{
CFStringRef cfName = (CFStringRef) CFDictionaryGetValue( cfMapDict, CFSTR(kXMLStdNameKey) );
if ( cfName != NULL && CFGetTypeID(cfName) == CFStringGetTypeID())
{
CFArrayRef cfNativeMapTemp = (CFArrayRef) CFDictionaryGetValue( cfMapDict, CFSTR(kXMLNativeMapArrayKey) );
if ( cfNativeMapTemp != NULL && CFGetTypeID(cfNativeMapTemp) == CFArrayGetTypeID() )
{
if ( CFDictionaryGetValue(cfAttribDict, cfName) == NULL )
{
CFDictionarySetValue( cfAttribDict, cfName, cfNativeMapTemp );
}
}
}
}
}
}
}
}
return cfReturnDict;
}
const char*
CLDAPBindData::Server( void )
{
return mServer;
}
CFStringRef
CLDAPBindData::ServerCFString( void )
{
return mServerCFString;
}
bool
CLDAPBindData::SSL( void )
{
return mSSL;
}
bool
CLDAPBindData::LDAPv2ReadOnly( void )
{
return mLDAPv2Only;
}
const char*
CLDAPBindData::UserName( void )
{
return mUserName;
}
const char*
CLDAPBindData::Password( void )
{
return mPassword;
}
CFDictionaryRef
CLDAPBindData::ComputerMap( void )
{
return mCFComputerMap;
}
const char*
CLDAPBindData::ComputerName( void )
{
return mComputerName;
}
const char*
CLDAPBindData::EnetAddress( void )
{
return mEnetAddr;
}