/* File: CLDAPv3Configs.cpp Contains: Code to parse a XML file and place the contents into a table of structs Copyright: © 2001 by Apple Computer, Inc., all rights reserved. NOT_FOR_OPEN_SOURCE */ #include "CLDAPv3Configs.h" #include #include // used for ::CFCopySearchPathForDirectoriesInDomains #include //used for strcpy, etc. #include //used for malloc #include #include //used for mkdir and stat #include //error logging //#include #include // try and catch macros #include #include #include #define kAllocatorDefault NULL // -------------------------------------------------------------------------------- // * CLDAPv3Configs // -------------------------------------------------------------------------------- CLDAPv3Configs::CLDAPv3Configs ( void ) { pConfigTable = nil; //pStdAttributeMapTuple = nil; //pStdRecordMapTuple = nil; fConfigTableLen = 0; fXMLData = nil; pXMLConfigLock = new DSMutexSemaphore(); } // CLDAPv3Configs // -------------------------------------------------------------------------------- // * ~CLDAPv3Configs () // -------------------------------------------------------------------------------- CLDAPv3Configs::~CLDAPv3Configs ( void ) { uInt32 iTableIndex = 0; // sInt32 siResult = eDSNoErr; sLDAPConfigData *pConfig = nil; //need to cleanup the config table ie. the internals for (iTableIndex=0; iTableIndexGetItemData( iTableIndex ); if (pConfig != nil) { // delete the contents of sLDAPConfigData here // not checking the return status of the clean here // since don't plan to continue CleanLDAPConfigData( pConfig ); // delete the sLDAPConfigData itself delete( pConfig ); pConfig = nil; // remove the table entry pConfigTable->RemoveItem( iTableIndex ); } } fConfigTableLen = 0; if ( pConfigTable != nil) { delete ( pConfigTable ); pConfigTable = nil; } if (pXMLConfigLock != nil) { delete(pXMLConfigLock); pXMLConfigLock = nil; } if (fXMLData != nil) { CFRelease(fXMLData); fXMLData = nil; } //free up the standard mapping tables after the config table is freed //siResult = CleanMapTuple(pStdAttributeMapTuple); //siResult = CleanMapTuple(pStdRecordMapTuple); } // ~CLDAPv3Configs // -------------------------------------------------------------------------------- // * Init (CPlugInRef, sMapTuple, sMapTuple) // -------------------------------------------------------------------------------- sInt32 CLDAPv3Configs::Init ( CPlugInRef *inConfigTable, uInt32 &inConfigTableLen, sMapTuple **inStdAttributeMapTuple, sMapTuple **inStdRecordMapTuple ) { sInt32 siResult = eDSNoErr; sLDAPConfigData *pConfig = nil; uInt32 sIndex = 0; uInt32 iTableIndex = 0; //Init is set up so that if it is called initially or by a custom call //it will keep on adding and deleting configs as required if (inConfigTableLen != 0) { fConfigTableLen = inConfigTableLen; } if ( inConfigTable == nil ) { inConfigTable = new CPlugInRef( nil ); } pConfigTable = inConfigTable; //check for Generic node which has server name "unknown" if (!CheckForConfig((char *)"unknown", sIndex)) { //build a default config entry that can be used when no config exists pConfig = MakeLDAPConfigData((char *)"Generic",(char *)"unknown",true,120,120,389,false, 0, 0, false, false, false); pConfigTable->AddItem( fConfigTableLen, pConfig ); fConfigTableLen++; } XMLConfigLock(); //read the XML Config file if (fXMLData != nil) { CFRelease(fXMLData); fXMLData = nil; } siResult = ReadXMLConfig(); XMLConfigUnlock(); //check if XML file was read if (siResult == eDSNoErr) { //need to set the Updated flag to false so that nodes will get Unregistered //if a config no longer exists for that entry //this needs to be done AFTER it is verified that a XML config file exists if (inConfigTableLen != 0) { //need to cycle through the config table for (iTableIndex=0; iTableIndexGetItemData( iTableIndex ); if (pConfig != nil) { pConfig->bUpdated = false; } } } //set up the config table XMLConfigLock(); siResult = ConfigLDAPServers(); XMLConfigUnlock(); } //set/update the number of configs in the table inConfigTableLen = fConfigTableLen; /* //create the default mapping tables if the mappings are nil here //use the hardcode inside this class if (pStdAttributeMapTuple == nil) { siResult = BuildDefaultStdAttributeMap(); } if (pStdRecordMapTuple == nil) { siResult = BuildDefaultStdRecordMap(); } //assign the default mappings to be returned //since they are also used back in CLDAPPlugIn directly if (inStdAttributeMapTuple != nil) { *inStdAttributeMapTuple = pStdAttributeMapTuple; } if (inStdRecordMapTuple != nil) { *inStdRecordMapTuple = pStdRecordMapTuple; } */ return( siResult ); } // Init // --------------------------------------------------------------------------- // * BuildDefaultStdAttributeMap // --------------------------------------------------------------------------- sInt32 CLDAPv3Configs::BuildDefaultStdAttributeMap ( void ) { sInt32 siResult = eDSNoErr; sMapTuple *pAttrMapTuple = nil; sPtrString *tempPtrString = nil; //KW in the future this routine will read a XML file or ? //KW the error return code might then be useful // note that we build this list in reverse order since it is easier to hook up the next // pointers that way if (pStdAttributeMapTuple != nil) { //free up the standard attribute mapping table as created internally //if we have one in the config file CleanMapTuple(pStdAttributeMapTuple); pStdAttributeMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrVFSOpts)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrVFSOpts); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("vfsopts")]; ::strcpy(pAttrMapTuple->fNative->fName,"vfsopts"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrVFSLinkDir)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrVFSLinkDir); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("vfsdir")]; ::strcpy(pAttrMapTuple->fNative->fName,"vfsdir"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrVFSDumpFreq)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrVFSDumpFreq); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("vfsdumpfreq")]; ::strcpy(pAttrMapTuple->fNative->fName,"vfsdumpfreq"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrVFSPassNo)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrVFSPassNo); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("passno")]; ::strcpy(pAttrMapTuple->fNative->fName,"passno"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrVFSType)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrVFSType); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("vfstype")]; ::strcpy(pAttrMapTuple->fNative->fName,"vfstype"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrIPAddress)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrIPAddress); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("ipaddress")]; ::strcpy(pAttrMapTuple->fNative->fName,"ipaddress"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrDNSName)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrDNSName); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("dnsname")]; ::strcpy(pAttrMapTuple->fNative->fName,"dnsname"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrURLForNSL)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrURLForNSL); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("networklocurl")]; ::strcpy(pAttrMapTuple->fNative->fName,"networklocurl"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrURL)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrURL); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("urldata")]; ::strcpy(pAttrMapTuple->fNative->fName,"urldata"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrNBPEntry)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrNBPEntry); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("nbpdata")]; ::strcpy(pAttrMapTuple->fNative->fName,"nbpdata"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrPhoneNumber)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrPhoneNumber); tempPtrString = new sPtrString; if ( tempPtrString != nil ) { ::memset( tempPtrString, 0, sizeof( sPtrString ) ); tempPtrString->fName = new char[1+::strlen("phone")]; ::strcpy(tempPtrString->fName,"phone"); tempPtrString->pNext = nil; } pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("telephone")]; ::strcpy(pAttrMapTuple->fNative->fName,"telephone"); pAttrMapTuple->fNative->pNext = tempPtrString; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrRecordAlias)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrRecordAlias); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("aliasdata")]; ::strcpy(pAttrMapTuple->fNative->fName,"aliasdata"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrGroupMembership)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrGroupMembership); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("userlist")]; ::strcpy(pAttrMapTuple->fNative->fName,"userlist"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrGroup)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrGroup); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("grouplist")]; ::strcpy(pAttrMapTuple->fNative->fName,"grouplist"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrAuthenticationHint)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrAuthenticationHint); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("hint")]; ::strcpy(pAttrMapTuple->fNative->fName,"hint"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrEMailAddress)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrEMailAddress); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("mail")]; ::strcpy(pAttrMapTuple->fNative->fName,"mail"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrMailAttribute)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrMailAttribute); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("applemail")]; ::strcpy(pAttrMapTuple->fNative->fName,"applemail"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrUserShell)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrUserShell); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("shell")]; ::strcpy(pAttrMapTuple->fNative->fName,"shell"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrHomeDirectory)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrHomeDirectory); tempPtrString = new sPtrString; if ( tempPtrString != nil ) { ::memset( tempPtrString, 0, sizeof( sPtrString ) ); tempPtrString->fName = new char[1+::strlen("home")]; ::strcpy(tempPtrString->fName,"home"); tempPtrString->pNext = nil; } pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("homeloc")]; ::strcpy(pAttrMapTuple->fNative->fName,"homeloc"); pAttrMapTuple->fNative->pNext = tempPtrString; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrNFSHomeDirectory)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrNFSHomeDirectory); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("nfshome")]; ::strcpy(pAttrMapTuple->fNative->fName,"nfshome"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrPrimaryGroupID)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrPrimaryGroupID); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("groupid")]; ::strcpy(pAttrMapTuple->fNative->fName,"groupid"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrPassword)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrPassword); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("passwd")]; ::strcpy(pAttrMapTuple->fNative->fName,"passwd"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrUniqueID)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrUniqueID); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("unixid")]; ::strcpy(pAttrMapTuple->fNative->fName,"unixid"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDS1AttrDistinguishedName)]; ::strcpy(pAttrMapTuple->fStandard,kDS1AttrDistinguishedName); pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("realname")]; ::strcpy(pAttrMapTuple->fNative->fName,"realname"); pAttrMapTuple->fNative->pNext = nil; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } pAttrMapTuple = new sMapTuple; if ( pAttrMapTuple != nil ) { ::memset( pAttrMapTuple, 0, sizeof( sMapTuple ) ); pAttrMapTuple->fStandard = new char[1+::strlen(kDSNAttrRecordName)]; ::strcpy(pAttrMapTuple->fStandard,kDSNAttrRecordName); tempPtrString = new sPtrString; if ( tempPtrString != nil ) { ::memset( tempPtrString, 0, sizeof( sPtrString ) ); tempPtrString->fName = new char[1+::strlen("sn")]; ::strcpy(tempPtrString->fName,"sn"); tempPtrString->pNext = nil; } pAttrMapTuple->fNative = new sPtrString; if ( pAttrMapTuple->fNative != nil ) { ::memset( pAttrMapTuple->fNative, 0, sizeof( sPtrString ) ); pAttrMapTuple->fNative->fName = new char[1+::strlen("cn")]; ::strcpy(pAttrMapTuple->fNative->fName,"cn"); pAttrMapTuple->fNative->pNext = tempPtrString; } tempPtrString = new sPtrString; if ( tempPtrString != nil ) { ::memset( tempPtrString, 0, sizeof( sPtrString ) ); tempPtrString->fName = new char[1+::strlen("dn")]; ::strcpy(tempPtrString->fName,"dn"); tempPtrString->pNext = nil; pAttrMapTuple->fNative->pNext->pNext = tempPtrString; } pAttrMapTuple->pNext = pStdAttributeMapTuple; pStdAttributeMapTuple = pAttrMapTuple; pAttrMapTuple = nil; } return( siResult ); } // BuildDefaultStdAttributeMap // --------------------------------------------------------------------------- // * BuildDefaultStdRecordMap // --------------------------------------------------------------------------- sInt32 CLDAPv3Configs::BuildDefaultStdRecordMap ( void ) { sInt32 siResult = eDSNoErr; sMapTuple *pRecMapTuple = nil; //KW in the future this routine will read a XML file or ? //KW the error return code might then be useful // note that we build this list in reverse order since it is easier to hook up the next // pointers that way if (pStdRecordMapTuple != nil) { //free up the standard record mapping table as created internally //if we have one in the config file CleanMapTuple(pStdRecordMapTuple); pStdRecordMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeQTSServer)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeQTSServer); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=qtsserver, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=qtsserver, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeLDAPServer)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeLDAPServer); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=ldapserver, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=ldapserver, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeWebServer)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeWebServer); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=webserver, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=webserver, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeNFS)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeNFS); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=nfs, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=nfs, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeSMBServer)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeSMBServer); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=smbserver, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=smbserver, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeFTPServer)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeFTPServer); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=ftpserver, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=ftpserver, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeAFPServer)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeAFPServer); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=afpserver, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=afpserver, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypePrinters)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypePrinters); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=printers, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=printers, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeMachines)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeMachines); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=machines, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=machines, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeMounts)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeMounts); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=mounts, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=mounts, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeGroupAliases)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeGroupAliases); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=groupaliases, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=groupaliases, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeUserAliases)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeUserAliases); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=peoplealiases, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=peoplealiases, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeGroups)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeGroups); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=groups, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=groups, o=company name"); pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } pRecMapTuple = new sMapTuple; if ( pRecMapTuple != nil ) { ::memset( pRecMapTuple, 0, sizeof( sMapTuple ) ); pRecMapTuple->fStandard = new char[1+::strlen(kDSStdRecordTypeUsers)]; ::strcpy(pRecMapTuple->fStandard,kDSStdRecordTypeUsers); pRecMapTuple->fNative = new sPtrString; if ( pRecMapTuple->fNative != nil ) { ::memset( pRecMapTuple->fNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fName = new char[1+::strlen("ou=people, o=company name")]; ::strcpy(pRecMapTuple->fNative->fName,"ou=people, o=company name"); //insert some object class data here pRecMapTuple->fNative->fSubNative = new sPtrString; if ( pRecMapTuple->fNative->fSubNative != nil ) { ::memset( pRecMapTuple->fNative->fSubNative, 0, sizeof( sPtrString ) ); pRecMapTuple->fNative->fSubNative->fName = new char[1+::strlen("*")]; ::strcpy(pRecMapTuple->fNative->fSubNative->fName,"*"); pRecMapTuple->fNative->fSubNative->pNext = nil; } pRecMapTuple->fNative->pNext = nil; } pRecMapTuple->pNext = pStdRecordMapTuple; pStdRecordMapTuple = pRecMapTuple; pRecMapTuple = nil; } return( siResult ); } // BuildDefaultStdRecordMap // --------------------------------------------------------------------------- // * CleanMapTuple // --------------------------------------------------------------------------- sInt32 CLDAPv3Configs::CleanMapTuple ( sMapTuple *inMapTuple ) { sInt32 siResult = eDSNoErr; sMapTuple *pMapTuple = nil; sPtrString *pPtrString = nil; sPtrString *pSubPtrString = nil; //KW is the error return code ever useful? pMapTuple = inMapTuple; while (pMapTuple != nil) { inMapTuple = pMapTuple->pNext; if (pMapTuple->fStandard != nil) { delete( pMapTuple->fStandard ); } pPtrString = pMapTuple->fNative; while (pPtrString != nil) { pMapTuple->fNative = pPtrString->pNext; pPtrString->fGroupSubNative = 0; while (pPtrString->fSubNative != nil) { pSubPtrString = pPtrString->fSubNative; pPtrString->fSubNative = pSubPtrString->pNext; if (pSubPtrString->fName != nil) { delete(pSubPtrString->fName); } //always assume that there will only be one layer of fSubNative in the sPtrString struct delete(pSubPtrString); } if (pPtrString->fName != nil) { delete( pPtrString->fName ); } pPtrString->pNext = nil; delete( pPtrString ); pPtrString = pMapTuple->fNative; } pMapTuple->pNext = nil; delete( pMapTuple ); pMapTuple = inMapTuple; } return( siResult ); } // CleanMapTuple // --------------------------------------------------------------------------- // * ReadXMLConfig // --------------------------------------------------------------------------- sInt32 CLDAPv3Configs::ReadXMLConfig ( void ) { sInt32 siResult = eDSNoErr; CFURLRef configFileURL = nil; CFURLRef configFileCorruptedURL = nil; CFDataRef xmlData; bool bReadFile = false; bool bCorruptedFile = false; bool bWroteFile = false; register CFIndex iPath; CFArrayRef aPaths = nil; char string[ PATH_MAX ]; char string2[ PATH_MAX ]; struct stat statResult; CFMutableDictionaryRef configDict; CFStringRef cfStringRef; sInt32 errorCode = 0; CFStringRef sBase = nil; CFStringRef sPath = nil; CFStringRef sCorruptedPath; //Config data is read from a XML file //KW eventually use Version from XML file to check against the code here? //Steps in the process: //1- see if the file exists //2- if it exists then try to read it //3- if existing file is corrupted then rename it and save it while creating a new default file //4- if file doesn't exist then create a new default file - make sure directories exist/if not create them // Get the local library search path -- only expect a single one aPaths = ::CFCopySearchPathForDirectoriesInDomains( kCFLibraryDirectory, kCFLocalDomainMask, true ); if ( aPaths != nil ) { iPath = ::CFArrayGetCount( aPaths ); if ( iPath != 0 ) { // count down here if more that the Local directory is specified // ie. in Local ( or user's home directory ). // for now reality is that there is NO countdown while (( iPath-- ) && (!bReadFile)) { configFileURL = (CFURLRef)::CFArrayGetValueAtIndex( aPaths, iPath ); // Append the subpath. sBase = ::CFURLCopyFileSystemPath( configFileURL, kCFURLPOSIXPathStyle ); sPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%s" ), sBase, "/Preferences/DirectoryService/DSLDAPv3PlugInConfig.plist" ); ::memset(string,0,PATH_MAX); ::CFStringGetCString( sPath, string, sizeof( string ), kCFStringEncodingUTF8 ); CShared::LogIt( 0x0F, (char *)"Checking for LDAP XML config file:" ); CShared::LogIt( 0x0F, string ); // Convert it back into a CFURL. configFileURL = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, sPath, kCFURLPOSIXPathStyle, false ); CFRelease( sPath ); // build with Create so okay to dealloac here sPath = nil; //step 1- see if the file exists //if not then make sure the directories exist or create them //then create a new file if necessary siResult = ::stat( string, &statResult ); //if file does not exist if (siResult != eDSNoErr) { //move down the path from the system defined local directory and check if it exists //if not create it sPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%s" ), sBase, "/Preferences" ); ::memset(string2,0,PATH_MAX); ::CFStringGetCString( sPath, string2, sizeof( string2 ), kCFStringEncodingUTF8 ); siResult = ::stat( string2, &statResult ); //if first sub directory does not exist if (siResult != eDSNoErr) { ::mkdir( string2 , 0775 ); ::chmod( string2, 0775 ); //above 0775 doesn't seem to work - looks like umask modifies it } CFRelease( sPath ); // build with Create so okay to dealloac here sPath = nil; //next subdirectory sPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%s" ), sBase, "/Preferences/DirectoryService" ); ::memset(string2,0,PATH_MAX); ::CFStringGetCString( sPath, string2, sizeof( string2 ), kCFStringEncodingUTF8 ); siResult = ::stat( string2, &statResult ); //if second sub directory does not exist if (siResult != eDSNoErr) { ::mkdir( string2 , 0775 ); ::chmod( string2, 0775 ); //above 0775 doesn't seem to work - looks like umask modifies it } CFRelease( sPath ); // build with Create so okay to dealloac here sPath = nil; //create a new dictionary for the file configDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, "DSLDAPv3PlugIn Version 1.5", kCFStringEncodingUTF8); CFDictionarySetValue( configDict, CFSTR( kXMLLDAPVersionKey ), cfStringRef ); CFRelease(cfStringRef); cfStringRef = nil; //build the standard types in here so that there is something to start with //siResult = BuildDefaultStdAttributeMap(); //siResult = BuildDefaultStdRecordMap(); //now populate the dictionary with the std mappings //siResult = AddDefaultArrays(configDict); CShared::LogIt( 0x0F, (char *)"Created a new LDAP XML config file since it did not exist" ); //convert the dict into a XML blob xmlData = CFPropertyListCreateXMLData( kCFAllocatorDefault, configDict); //write the XML to the config file siResult = CFURLWriteDataAndPropertiesToResource( configFileURL, xmlData, NULL, &errorCode); //KW check the error code and the result? CFRelease(configDict); configDict = nil; CFRelease(xmlData); xmlData = nil; } // file does not exist so creating one chmod( string, S_IRUSR | S_IWUSR ); // Read the XML property list file bReadFile = CFURLCreateDataAndPropertiesFromResource( kAllocatorDefault, configFileURL, &xmlData, // place to put file data NULL, NULL, &siResult); } // while (( iPath-- ) && (!bReadFile)) } // if ( iPath != 0 ) CFRelease(aPaths); // seems okay since Created above aPaths = nil; }// if ( aPaths != nil ) if (bReadFile) { fXMLData = xmlData; //check if this XML blob is a property list and can be made into a dictionary if (!VerifyXML()) { //if it is not then say the file is corrupted and save off the corrupted file CShared::LogIt( 0x0F, (char *)"LDAP XML config file is corrupted" ); bCorruptedFile = true; //here we need to make a backup of the file - why? - because // Append the subpath. sCorruptedPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%s" ), sBase, "/Preferences/DirectoryService/DSLDAPv3PlugInConfigCorrupted.plist" ); // Convert it into a CFURL. configFileCorruptedURL = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, sCorruptedPath, kCFURLPOSIXPathStyle, false ); CFRelease( sCorruptedPath ); // build with Create so okay to dealloac here sCorruptedPath = nil; //write the XML to the corrupted copy of the config file bWroteFile = CFURLWriteDataAndPropertiesToResource( configFileCorruptedURL, xmlData, NULL, &errorCode); //KW check the error code and the result? CFRelease(xmlData); xmlData = nil; } } else //existing file is unreadable { CShared::LogIt( 0x0F, (char *)"LDAP XML config file is unreadable" ); bCorruptedFile = true; //siResult = eDSPlugInConfigFileError; // not an error since we will attempt to recover } if (bCorruptedFile) { //create a new dictionary for the file configDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, "DSLDAPv3PlugIn Version 1.5", kCFStringEncodingUTF8); CFDictionarySetValue( configDict, CFSTR( kXMLLDAPVersionKey ), cfStringRef ); CFRelease(cfStringRef); cfStringRef = nil; /* //check the std defaults if by off chance the above write of a new file was corrupted if (pStdAttributeMapTuple == nil) { siResult = BuildDefaultStdAttributeMap(); } if (pStdRecordMapTuple == nil) { siResult = BuildDefaultStdRecordMap(); } //now populate the dictionary with the std mappings //code makes sure that the arrays don't already exist although doesn't matter since configDict is new siResult = AddDefaultArrays(configDict); */ CShared::LogIt( 0x0F, (char *)"Writing a new LDAP XML config file" ); //convert the dict into a XML blob xmlData = CFPropertyListCreateXMLData( kCFAllocatorDefault, configDict); //assume that the XML blob is good since we created it here fXMLData = xmlData; //write the XML to the config file siResult = CFURLWriteDataAndPropertiesToResource( configFileURL, xmlData, NULL, &errorCode); //KW check the error code and the result? CFRelease(configDict); configDict = nil; } if (configFileURL != nil) { CFRelease(configFileURL); // seems okay to dealloc since Create used and done with it now configFileURL = nil; } if (configFileCorruptedURL != nil) { CFRelease(configFileCorruptedURL); // seems okay to dealloc since Create used and done with it now configFileCorruptedURL = nil; } if (sBase != nil) { CFRelease( sBase ); // built with Copy so okay to dealloc sBase = nil; } return( siResult ); } // ReadXMLConfig // --------------------------------------------------------------------------- // * WriteXMLConfig // --------------------------------------------------------------------------- sInt32 CLDAPv3Configs::WriteXMLConfig ( void ) { sInt32 siResult = eDSNoErr; CFURLRef configFileURL; // CFURLRef configFileBackupURL; // CFDataRef xmlData; bool bWroteFile = false; // bool bReadFile = false; register CFIndex iPath; CFArrayRef aPaths = nil; char string[ PATH_MAX ]; struct stat statResult; sInt32 errorCode = 0; //Config data is written to a XML file //Steps in the process: //1- see if the file exists //2- if it exists then overwrite it //3- rename existing file and save it while creating a new file //4- if file doesn't exist then create a new default file - make sure directories exist/if not create them //make sure file permissions are root only // Get the local library search path -- only expect a single one aPaths = ::CFCopySearchPathForDirectoriesInDomains( kCFLibraryDirectory, kCFLocalDomainMask, true ); if ( aPaths != nil ) { iPath = ::CFArrayGetCount( aPaths ); if ( iPath != 0 ) { // count down here if more that the Local directory is specified // ie. in Local ( or user's home directory ). // for now reality is that there is NO countdown while (( iPath-- ) && (!bWroteFile)) { configFileURL = (CFURLRef)::CFArrayGetValueAtIndex( aPaths, iPath ); CFStringRef sBase, sPath; // Append the subpath. sBase = ::CFURLCopyFileSystemPath( configFileURL, kCFURLPOSIXPathStyle ); sPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%s" ), sBase, "/Preferences/DirectoryService/DSLDAPv3PlugInConfig.plist" ); ::memset(string,0,PATH_MAX); ::CFStringGetCString( sPath, string, sizeof( string ), kCFStringEncodingUTF8 ); CShared::LogIt( 0x0F, (char *)"Checking for LDAP XML config file:" ); CShared::LogIt( 0x0F, string ); // Convert it back into a CFURL. configFileURL = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, sPath, kCFURLPOSIXPathStyle, false ); CFRelease( sPath ); // build with Create so okay to dealloac here sPath = nil; //step 1- see if the file exists //if not then make sure the directories exist or create them //then write the file siResult = ::stat( string, &statResult ); //if file exists then we make a backup copy - why? - because /*if (siResult == eDSNoErr) { CFStringRef sBackupPath; // Append the subpath. sBackupPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%@/%s" ), sBase, "/Preferences/DirectoryService/DSLDAPv3PlugInConfigBackup.plist" ); // Convert it into a CFURL. configFileBackupURL = ::CFURLCreateWithFileSystemPath( kCFAllocatorDefault, sBackupPath, kCFURLPOSIXPathStyle, false ); CFRelease( sBackupPath ); // build with Create so okay to dealloac here sBackupPath = nil; // Read the old XML property list file bReadFile = CFURLCreateDataAndPropertiesFromResource( kAllocatorDefault, configFileURL, &xmlData, // place to put file data NULL, NULL, &siResult); //write the XML to the backup config file if (bReadFile) { bWroteFile = CFURLWriteDataAndPropertiesToResource( configFileBackupURL, xmlData, NULL, &errorCode); //KW check the error code and the result? CFRelease(xmlData); xmlData = nil; } }*/ //if file does not exist if (siResult != eDSNoErr) { siResult = eDSNoErr; //move down the path from the system defined local directory and check if it exists //if not create it sPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%s" ), sBase, "/Preferences" ); ::memset(string,0,PATH_MAX); ::CFStringGetCString( sPath, string, sizeof( string ), kCFStringEncodingUTF8 ); siResult = ::stat( string, &statResult ); //if first sub directory does not exist if (siResult != eDSNoErr) { siResult = eDSNoErr; ::mkdir( string , 0775 ); ::chmod( string, 0775 ); //above 0775 doesn't seem to work - looks like umask modifies it } CFRelease( sPath ); // build with Create so okay to dealloac here sPath = nil; //next subdirectory sPath = ::CFStringCreateWithFormat( kCFAllocatorDefault, NULL, CFSTR( "%@/%s" ), sBase, "/Preferences/DirectoryService" ); ::memset(string,0,PATH_MAX); ::CFStringGetCString( sPath, string, sizeof( string ), kCFStringEncodingUTF8 ); siResult = ::stat( string, &statResult ); //if second sub directory does not exist if (siResult != eDSNoErr) { siResult = eDSNoErr; ::mkdir( string , 0775 ); ::chmod( string, 0775 ); //above 0775 doesn't seem to work - looks like umask modifies it } CFRelease( sPath ); // build with Create so okay to dealloac here sPath = nil; } // file does not exist so checking directory path to enable write of a new file //now write the updated file if (fXMLData != nil) { //write the XML to the config file bWroteFile = CFURLWriteDataAndPropertiesToResource( configFileURL, fXMLData, NULL, &errorCode); //check the error code and the result? } CFRelease( sBase ); // built with Copy so okay to dealloc sBase = nil; CFRelease(configFileURL); // seems okay to dealloc since Create used and done with it now configFileURL = nil; } // while (( iPath-- ) && (!bWroteFile)) } // if ( iPath != 0 ) CFRelease(aPaths); // seems okay since Created above aPaths = nil; }// if ( aPaths != nil ) if (bWroteFile) { CShared::LogIt( 0x0F, (char *)"Have written the LDAP XML config file:" ); CShared::LogIt( 0x0F, string ); siResult = eDSNoErr; } else { CShared::LogIt( 0x0F, (char *)"LDAP XML config file has NOT been written" ); CShared::LogIt( 0x0F, (char *)"Update to LDAP Config File Failed" ); siResult = eDSPlugInConfigFileError; } return( siResult ); } // WriteXMLConfig // --------------------------------------------------------------------------- // * SetXMLConfig // --------------------------------------------------------------------------- sInt32 CLDAPv3Configs::SetXMLConfig ( CFDataRef xmlData ) { CFDataRef currentXMLData = fXMLData; fXMLData = xmlData; if (VerifyXML()) { // looks ok, let's use it if (currentXMLData != nil) { CFRelease(currentXMLData); currentXMLData = nil; } CFRetain(fXMLData); return eDSNoErr; //return ConfigLDAPServers(); // this refreshes the registered nodes } else { // go back to what we had fXMLData = currentXMLData; return eDSInvalidPlugInConfigData; } } // --------------------------------------------------------------------------- // * GetXMLConfig // --------------------------------------------------------------------------- CFDataRef CLDAPv3Configs::GetXMLConfig ( void ) { return fXMLData; } sInt32 CLDAPv3Configs::AddDefaultArrays ( CFMutableDictionaryRef inDict ) { CFMutableArrayRef cfArrayRef = nil; CFMutableDictionaryRef cfDictRef = nil; CFIndex cfMapCount = 0; CFIndex cfNativeMapCount = 0; CFIndex cfSubNativeMapCount = 0; CFStringRef cfStringRef = nil; CFMutableArrayRef cfNativeArrayRef = nil; CFMutableArrayRef cfSubNativeArrayRef = nil; sMapTuple *pMapTuple = nil; sInt32 siResult = eDSNoErr; sPtrString *pPtrString = nil; sPtrString *pSubPtrString = nil; CFMutableDictionaryRef cfSubDictRef = nil; // if this already exists in the dictionary then remove it if ( CFDictionaryContainsKey( inDict, CFSTR( kXMLDefaultAttrTypeMapArrayKey ) ) ) { //cfArrayRef = (CFMutableArrayRef)CFDictionaryGetValue( inDict, CFSTR( kXMLDefaultAttrTypeMapArrayKey ) ); //KW is this sufficient ie. does remove do the release as well CFDictionaryRemoveValue( inDict, CFSTR( kXMLDefaultAttrTypeMapArrayKey ) ); //CFRelease(cfArrayRef); //cfArrayRef = nil; } //check if this already exists in the dictionary if ( !CFDictionaryContainsKey( inDict, CFSTR( kXMLDefaultAttrTypeMapArrayKey ) ) ) { //create the def attr array and add to the dictionary cfArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFDictionarySetValue( inDict, CFSTR(kXMLDefaultAttrTypeMapArrayKey), cfArrayRef); //release then get from the dictionary CFRelease(cfArrayRef); cfArrayRef = nil; cfArrayRef = (CFMutableArrayRef)CFDictionaryGetValue( inDict, CFSTR( kXMLDefaultAttrTypeMapArrayKey ) ); cfMapCount = 0; //go through the default attr mappings and add them to the array pMapTuple = pStdAttributeMapTuple; while (pMapTuple != nil) { cfDictRef = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); CFArrayInsertValueAtIndex(cfArrayRef, cfMapCount, cfDictRef); if (pMapTuple->fStandard != nil) { cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, pMapTuple->fStandard, kCFStringEncodingUTF8); CFDictionarySetValue( cfDictRef, CFSTR(kXMLStdNameKey), cfStringRef); CFRelease(cfStringRef); cfStringRef = nil; //next index value cfMapCount++; } cfNativeArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFDictionarySetValue( cfDictRef, CFSTR(kXMLNativeMapArrayKey), cfNativeArrayRef); //release then get from the dictionary CFRelease(cfNativeArrayRef); cfNativeArrayRef = nil; cfNativeArrayRef = (CFMutableArrayRef)CFDictionaryGetValue( cfDictRef, CFSTR( kXMLNativeMapArrayKey ) ); cfNativeMapCount = 0; pPtrString = pMapTuple->fNative; while (pPtrString != nil) { if (pPtrString->fName != nil) { cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, pPtrString->fName, kCFStringEncodingUTF8); CFArrayInsertValueAtIndex(cfNativeArrayRef, cfNativeMapCount, cfStringRef); CFRelease(cfStringRef); cfStringRef = nil; //next index value cfNativeMapCount++; } pPtrString = pPtrString->pNext; } pMapTuple = pMapTuple->pNext; if (cfDictRef != nil) { CFRelease(cfDictRef); cfDictRef = nil; } } } // if this already exists in the dictionary then remove it if ( CFDictionaryContainsKey( inDict, CFSTR( kXMLDefaultRecordTypeMapArrayKey ) ) ) { //cfArrayRef = (CFMutableArrayRef)CFDictionaryGetValue( inDict, CFSTR( kXMLDefaultRecordTypeMapArrayKey ) ); //KW is this sufficient ie. does remove do the release as well CFDictionaryRemoveValue( inDict, CFSTR( kXMLDefaultRecordTypeMapArrayKey ) ); //CFRelease(cfArrayRef); //cfArrayRef = nil; } //check if this already exists in the dictionary if ( !CFDictionaryContainsKey( inDict, CFSTR( kXMLDefaultRecordTypeMapArrayKey ) ) ) { //create the def record array and add to the dictionary cfArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFDictionarySetValue( inDict, CFSTR(kXMLDefaultRecordTypeMapArrayKey), cfArrayRef); //release then get from the dictionary CFRelease(cfArrayRef); cfArrayRef = nil; cfArrayRef = (CFMutableArrayRef)CFDictionaryGetValue( inDict, CFSTR( kXMLDefaultRecordTypeMapArrayKey ) ); cfMapCount = 0; //go through the default record mappings and add them to the array pMapTuple = pStdRecordMapTuple; while (pMapTuple != nil) { cfDictRef = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); CFArrayInsertValueAtIndex(cfArrayRef, cfMapCount, cfDictRef); if (pMapTuple->fStandard != nil) { cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, pMapTuple->fStandard, kCFStringEncodingUTF8); CFDictionarySetValue( cfDictRef, CFSTR(kXMLStdNameKey), cfStringRef); CFRelease(cfStringRef); cfStringRef = nil; //next index value cfMapCount++; } cfNativeArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFDictionarySetValue( cfDictRef, CFSTR(kXMLNativeMapArrayKey), cfNativeArrayRef); //release then get from the dictionary CFRelease(cfNativeArrayRef); cfNativeArrayRef = nil; cfNativeArrayRef = (CFMutableArrayRef)CFDictionaryGetValue( cfDictRef, CFSTR( kXMLNativeMapArrayKey ) ); cfNativeMapCount = 0; pPtrString = pMapTuple->fNative; while (pPtrString != nil) { if (pPtrString->fSubNative != nil) //case used for ObjectClasses and SearchBase separated { cfSubDictRef = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); if (pPtrString->fName != nil) { cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, pPtrString->fName, kCFStringEncodingUTF8); CFDictionarySetValue( cfSubDictRef, CFSTR(kXMLSearchBase), cfStringRef); CFRelease(cfStringRef); cfStringRef = nil; } cfSubNativeArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); CFDictionarySetValue( cfSubDictRef, CFSTR(kXMLObjectClasses), cfSubNativeArrayRef); //release then get from the dictionary CFRelease(cfSubNativeArrayRef); cfSubNativeArrayRef = nil; cfSubNativeArrayRef = (CFMutableArrayRef)CFDictionaryGetValue( cfSubDictRef, CFSTR( kXMLObjectClasses ) ); cfSubNativeMapCount = 0; pSubPtrString = pPtrString->fSubNative; if( pSubPtrString != nil) { if (pSubPtrString->fGroupSubNative != 0) //ie. do nothing if zero { cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, "OR", kCFStringEncodingUTF8); CFDictionarySetValue( cfSubDictRef, CFSTR(kXMLGroupObjectClasses), cfStringRef); CFRelease(cfStringRef); cfStringRef = nil; } } while( pSubPtrString != nil) { if (pSubPtrString->fName != nil) { cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, pSubPtrString->fName, kCFStringEncodingUTF8); CFArrayInsertValueAtIndex(cfSubNativeArrayRef, cfSubNativeMapCount, cfStringRef); CFRelease(cfStringRef); cfStringRef = nil; //next index value cfSubNativeMapCount++; } pSubPtrString = pSubPtrString->pNext; } CFArrayInsertValueAtIndex(cfNativeArrayRef, cfNativeMapCount, cfSubDictRef); CFRelease(cfSubDictRef); cfSubDictRef = nil; //next index value cfNativeMapCount++; } else { if (pPtrString->fName != nil) { cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, pPtrString->fName, kCFStringEncodingUTF8); CFArrayInsertValueAtIndex(cfNativeArrayRef, cfNativeMapCount, cfStringRef); CFRelease(cfStringRef); cfStringRef = nil; //next index value cfNativeMapCount++; } } pPtrString = pPtrString->pNext; } pMapTuple = pMapTuple->pNext; if (cfDictRef != nil) { CFRelease(cfDictRef); cfDictRef = nil; } } } return siResult; } // AddDefaultArrays // --------------------------------------------------------------------------- // * VerifyXML // --------------------------------------------------------------------------- bool CLDAPv3Configs::VerifyXML ( void ) { bool verified = false; CFStringRef errorString; CFPropertyListRef configPropertyList; // char *configVersion = nil; //KW need to add in check on the version string if (fXMLData != nil) { // extract the config dictionary from the XML data. configPropertyList = CFPropertyListCreateFromXMLData( kAllocatorDefault, fXMLData, kCFPropertyListImmutable, &errorString); if (configPropertyList != nil ) { //make the propertylist a dict if ( CFDictionaryGetTypeID() == CFGetTypeID( configPropertyList ) ) { verified = true; } CFRelease(configPropertyList); configPropertyList = nil; } } return( verified); } // VerifyXML // -------------------------------------------------------------------------------- // * ConfigDHCPObtainedLDAPServer // -------------------------------------------------------------------------------- void CLDAPv3Configs::ConfigDHCPObtainedLDAPServer ( char *inServer, char *inMapSearchBase, int inPortNumber, bool inIsSSL, uInt32 &inConfigTableLen ) { sInt32 siResult = eDSNoErr; CFDataRef ourXMLData = nil; CFDataRef newXMLData = nil; ourXMLData = RetrieveServerMappings( inServer, inMapSearchBase, inPortNumber, inIsSSL ); if (ourXMLData != nil) { //here we will make sure that the server location and port/SSL in the XML data is the same as given above //we also make sure that the MakeDefLDAPFlag is set so that this gets added to the Automatic search policy newXMLData = VerifyAndUpdateServerLocation(inServer, inPortNumber, inIsSSL, ourXMLData); //don't check return if (newXMLData != nil) { CFRelease(ourXMLData); ourXMLData = newXMLData; newXMLData = nil; } siResult = AddDefaultLDAPServer(ourXMLData); if (siResult != eDSNoErr) { syslog(LOG_INFO,"DSLDAPv3PlugIn: DHCP option 95 obtained [%s] LDAP server not added to search policy due to server mappings format error.", inServer); } //set/update the number of configs in the table inConfigTableLen = fConfigTableLen; } else { syslog(LOG_INFO,"DSLDAPv3PlugIn: DHCP option 95 obtained [%s] LDAP server not added to search policy due to server mappings error.", inServer); } } // ConfigDHCPObtainedLDAPServer // --------------------------------------------------------------------------- // * ConfigLDAPServers // --------------------------------------------------------------------------- sInt32 CLDAPv3Configs::ConfigLDAPServers ( void ) { sInt32 siResult = eDSNoErr; CFStringRef errorString; CFPropertyListRef configPropertyList = nil; CFMutableDictionaryRef configDict = nil; CFArrayRef cfArrayRef = nil; CFIndex cfConfigCount = 0; CFDataRef xmlData = nil; char *configVersion = nil; CFStringRef cfStringRef; try { if (fXMLData != nil) { // extract the config dictionary from the XML data. configPropertyList = CFPropertyListCreateFromXMLData( kAllocatorDefault, fXMLData, kCFPropertyListImmutable, //could also use kCFPropertyListImmutable, kCFPropertyListMutableContainers &errorString); if (configPropertyList != nil ) { //make the propertylist a dict if ( CFDictionaryGetTypeID() == CFGetTypeID( configPropertyList ) ) { configDict = (CFMutableDictionaryRef) configPropertyList; } if (configDict != nil) { //get version, useThisFileFlag(potential feature), defaults mappings and array of LDAP server configs //config file version configVersion = GetVersion(configDict); if ( configVersion == nil ) throw( (sInt32)eDSVersionMismatch ); //KW need eDSPlugInConfigFileError if (configVersion != nil) { CShared::LogIt( 0x0F, (char *)"Have successfully read the LDAP XML config file:" ); //if config file is up to date with latest default mappings then use them if (strcmp(configVersion,"DSLDAPv3PlugIn Version 1.5") == 0) { /* //array of DefaultRecordTypeMapArray cfArrayRef = nil; cfArrayRef = GetDefaultRecordTypeMapArray(configDict); if (cfArrayRef != nil) { if (pStdRecordMapTuple != nil) { //free up the standard record mapping table as created internally //if we have one in the config file CleanMapTuple(pStdRecordMapTuple); pStdRecordMapTuple = nil; } pStdRecordMapTuple = BuildMapTuple(cfArrayRef); } // if (cfArrayRef != nil) ie. an array of DefaultRecordTypeMapArray //array of DefaultAttrTypeMapArray cfArrayRef = nil; cfArrayRef = GetDefaultAttrTypeMapArray(configDict); if (cfArrayRef != nil) { if (pStdAttributeMapTuple != nil) { //free up the standard attribute mapping table as created internally //if we have one in the config file CleanMapTuple(pStdAttributeMapTuple); pStdAttributeMapTuple = nil; } pStdAttributeMapTuple = BuildMapTuple(cfArrayRef); } // if (cfArrayRef != nil) ie. an array of DefaultAttrTypeMapArray */ } else { // update the version // replace the default mappings in the configDict with the generated standard ones // write the config file out to pick up the generated default mappings //remove old and add proper version CFDictionaryRemoveValue( configDict, CFSTR( kXMLLDAPVersionKey ) ); cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, "DSLDAPv3PlugIn Version 1.5", kCFStringEncodingUTF8); CFDictionarySetValue( configDict, CFSTR( kXMLLDAPVersionKey ), cfStringRef ); CFRelease(cfStringRef); cfStringRef = nil; /* //generate the default mapping tables if the mappings are nil if (pStdAttributeMapTuple == nil) { siResult = BuildDefaultStdAttributeMap(); } if (pStdRecordMapTuple == nil) { siResult = BuildDefaultStdRecordMap(); } //now populate the dictionary with the std mappings siResult = AddDefaultArrays(configDict); */ //convert the dict into a XML blob xmlData = CFPropertyListCreateXMLData( kCFAllocatorDefault, configDict); //replace the XML data blob siResult = SetXMLConfig(xmlData); //release this reference here CFRelease(xmlData); xmlData = nil; //write the file out to save the change if (siResult == eDSNoErr) { WriteXMLConfig(); } } //array of LDAP server configs cfArrayRef = nil; cfArrayRef = GetConfigArray(configDict); if (cfArrayRef != nil) { //now we can retrieve each config cfConfigCount = ::CFArrayGetCount( cfArrayRef ); //if (cfConfigCount == 0) //assume that this file has no Servers in it //and simply proceed forward ie. no Node will get registered from data in this file //loop through the configs //use iConfigIndex for the access to the cfArrayRef //use fConfigTableLen for the index to add to the table since we add at the end for (sInt32 iConfigIndex = 0; iConfigIndex < cfConfigCount; iConfigIndex++) { CFDictionaryRef serverConfigDict = nil; CFDictionaryRef suppliedServerDict = nil; serverConfigDict = (CFDictionaryRef)::CFArrayGetValueAtIndex( cfArrayRef, iConfigIndex ); if ( serverConfigDict != nil ) { //here we check the serverConfigDict if it indicates server mappings suppliedServerDict = CheckForServerMappings(serverConfigDict); if (suppliedServerDict != nil) { siResult = MakeLDAPConfig(suppliedServerDict, fConfigTableLen); CFRelease(suppliedServerDict); suppliedServerDict = nil; } else { siResult = MakeLDAPConfig(serverConfigDict, fConfigTableLen); } } } // loop over configs //CFRelease( cfArrayRef ); // no since pointer only from Get } // if (cfArrayRef != nil) ie. an array of LDAP configs exists delete(configVersion); }//if (configVersion != nil) // don't release the configDict since it is the cast configPropertyList }//if (configDict != nil) CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; }//if (configPropertyList != nil ) } // fXMLData != nil } // try catch ( sInt32 err ) { siResult = err; if (configPropertyList != nil) { CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; } } return( siResult ); } // ConfigLDAPServers //------------------------------------------------------------------------------------ // * RetrieveServerMappings //------------------------------------------------------------------------------------ CFDataRef CLDAPv3Configs::RetrieveServerMappings ( char *inServer, char *inMapSearchBase, int inPortNumber, bool inIsSSL ) { sInt32 siResult = eDSNoErr; bool bResultFound = false; int ldapMsgId = -1; LDAPMessage *result = nil; int ldapReturnCode = 0; char *attrs[2] = {"description",NULL}; BerElement *ber; struct berval **bValues; char *pAttr = nil; LDAP *serverHost = nil; CFDataRef ourMappings = nil; if ( (inServer != nil) && (inPortNumber != 0) ) { serverHost = ldap_init( inServer, inPortNumber ); if (serverHost != nil) { if (inIsSSL) { int ldapOptVal = LDAP_OPT_X_TLS_HARD; ldap_set_option(serverHost, LDAP_OPT_X_TLS, &ldapOptVal); } if (inMapSearchBase == nil) { ldapMsgId = ldap_search( serverHost, "", LDAP_SCOPE_SUBTREE, "(&(objectclass=*)(ou=macosxodconfig))", attrs, 0); } else { ldapMsgId = ldap_search( serverHost, inMapSearchBase, LDAP_SCOPE_SUBTREE, "(&(objectclass=*)(ou=macosxodconfig))", attrs, 0); } //here is the call to the LDAP server asynchronously which requires // host handle, search base, search scope(LDAP_SCOPE_SUBTREE for all), search filter, // attribute list (NULL for all), return attrs values flag // Note: asynchronous call is made so that a MsgId can be used for future calls // This returns us the message ID which is used to query the server for the results //TODO KW do we want a retry here? if ( ldapMsgId == -1 ) { bResultFound = false; } else { bResultFound = true; //retrieve the actual LDAP record data for use internally //useful only from the read-only perspective struct timeval tv; tv.tv_sec = 60; tv.tv_usec = 0; ldapReturnCode = ldap_result(serverHost, ldapMsgId, 0, &tv, &result); } if ( ( bResultFound ) && ( ldapReturnCode == LDAP_RES_SEARCH_ENTRY ) ) { //get the XML data here //parse the attributes in the result - should only be one ie. macosxodmappings for ( pAttr = ldap_first_attribute (serverHost, result, &ber ); pAttr != NULL; pAttr = ldap_next_attribute(serverHost, result, ber ) ) { if (( bValues = ldap_get_values_len (serverHost, result, pAttr )) != NULL) { // should be only one value of the attribute if ( bValues[0] != NULL ) { ourMappings = CFDataCreate(NULL,(UInt8 *)(bValues[0]->bv_val), bValues[0]->bv_len); } ldap_value_free_len(bValues); } // if bValues = ldap_get_values_len ... if (pAttr != nil) { ldap_memfree( pAttr ); } } // for ( loop over ldap_next_attribute ) if (ber != nil) { ber_free( ber, 0 ); } ldap_msgfree( result ); result = nil; siResult = eDSNoErr; } else if (ldapReturnCode == LDAP_TIMEOUT) { siResult = eDSServerTimeout; syslog(LOG_INFO,"DSLDAPv3PlugIn: Retrieval of Server Mappings for [%s] LDAP server has timed out.", inServer); if ( result != nil ) { ldap_msgfree( result ); result = nil; } } else { siResult = eDSRecordNotFound; syslog(LOG_INFO,"DSLDAPv3PlugIn: Server Mappings for [%s] LDAP server not found.", inServer); if ( result != nil ) { ldap_msgfree( result ); result = nil; } } ldap_unbind( serverHost ); } // if (serverHost != nil) } // if ( (inServer != nil) && (inPortNumber != 0) ) return( ourMappings ); } // RetrieveServerMappings //------------------------------------------------------------------------------------ // * WriteServerMappings //------------------------------------------------------------------------------------ sInt32 CLDAPv3Configs::WriteServerMappings ( char* userName, char* password, CFDataRef inMappings ) { sInt32 siResult = eDSNoErr; LDAP *serverHost = nil; CFStringRef errorString; CFPropertyListRef configPropertyList = nil; CFMutableDictionaryRef serverConfigDict = nil; char *server = nil; int portNumber = 389; char *tmpBuff = nil; CFIndex cfBuffSize = 1024; CFStringRef cfStringRef = nil; CFBooleanRef cfBool = nil; CFNumberRef cfNumber = nil; bool cfNumBool = false; char *mapSearchBase = nil; bool bIsSSL = false; int ldapReturnCode = 0; int bindMsgId = 0; LDAPMessage *result = nil; char *ldapDNString = nil; uInt32 ldapDNLength = 0; char *ourXMLBlob = nil; char *ouvals[2]; char *mapvals[2]; char *ocvals[3]; LDAPMod oumod; LDAPMod mapmod; LDAPMod ocmod; LDAPMod *mods[4]; try { if (inMappings != nil) { // extract the config dictionary from the XML data. configPropertyList = CFPropertyListCreateFromXMLData( kAllocatorDefault, inMappings, kCFPropertyListImmutable, //could also use kCFPropertyListImmutable, kCFPropertyListMutableContainers &errorString); if (configPropertyList != nil ) { //make the propertylist a dict if ( CFDictionaryGetTypeID() == CFGetTypeID( configPropertyList ) ) { serverConfigDict = (CFMutableDictionaryRef) configPropertyList; //don't need mutable really } if (serverConfigDict != nil) { //KW assume that the extracted strings will be significantly less than 1024 characters tmpBuff = (char *)::calloc(1, 1024); // retrieve all the relevant values (mapsearchbase, IsSSL) // to enable server mapping write //need to get the server name first if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLServerKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLServerKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { server = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(server, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLIsSSLFlagKey ) ) ) { cfBool= (CFBooleanRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLIsSSLFlagKey ) ); if (cfBool != nil) { bIsSSL = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get if (bIsSSL) { portNumber = 636; } } } if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLPortNumberKey ) ) ) { cfNumber = (CFNumberRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLPortNumberKey ) ); if ( cfNumber != nil ) { cfNumBool = CFNumberGetValue(cfNumber, kCFNumberIntType, &portNumber); //CFRelease(cfNumber); // no since pointer only from Get } } if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLMapSearchBase ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLMapSearchBase ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { mapSearchBase = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(mapSearchBase, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } //free up the tmpBuff free( tmpBuff ); tmpBuff = nil; // don't release the serverConfigDict since it is the cast configPropertyList }//if (serverConfigDict != nil) CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; }//if (configPropertyList != nil ) // JT do something different for SSL here serverHost = ldap_init( server, portNumber ); if ( serverHost == nil ) throw( (sInt32)eDSCannotAccessSession ); if ( bIsSSL ) { int ldapOptVal = LDAP_OPT_X_TLS_HARD; ldap_set_option(serverHost, LDAP_OPT_X_TLS, &ldapOptVal); } bindMsgId = ldap_bind( serverHost, userName, password, LDAP_AUTH_SIMPLE ); if ( bindMsgId == -1 ) { throw( (sInt32)eDSCannotAccessSession ); } { struct timeval tv; tv.tv_sec = 120; //openTO tv.tv_usec = 0; ldapReturnCode = ldap_result(serverHost, bindMsgId, 0, &tv, &result); } if ( ldapReturnCode == -1 ) { throw( (sInt32)eDSCannotAccessSession ); } else if ( ldapReturnCode == 0 ) { // timed out, let's forget it //ldap_abandon(outLDAPHost, bindMsgId); ldap_unbind( serverHost ); serverHost = NULL; throw( (sInt32)eDSCannotAccessSession ); } else if ( ldap_result2error(serverHost, result, 1) != LDAP_SUCCESS ) { throw( (sInt32)eDSCannotAccessSession ); } if ( (serverHost != nil) && (mapSearchBase != nil) ) { //we use "ou" for the DN always: //"ou = macosxodconfig, mapSearchBase" ldapDNLength = 21 + strlen(mapSearchBase); ldapDNString = (char *)calloc(1, ldapDNLength + 1); strcpy(ldapDNString,"ou = macosxodconfig, "); strcat(ldapDNString,mapSearchBase); //attempt to delete what is there if anything ldapReturnCode = ldap_delete_s( serverHost, ldapDNString); if ( ( ldapReturnCode == LDAP_INSUFFICIENT_ACCESS ) || ( ldapReturnCode == LDAP_INVALID_CREDENTIALS ) ) { siResult = eDSPermissionError; } else if ( ldapReturnCode == LDAP_NO_SUCH_OBJECT ) { siResult = eDSRecordNotFound; } else if ( ldapReturnCode != LDAP_SUCCESS ) { siResult = eDSBogusServer; } if ( (siResult == eDSRecordNotFound) || (siResult == eDSNoErr) ) { //make the XML blob a manageable char* CFRange aRange; aRange.location = 0; aRange.length = CFDataGetLength(inMappings); ourXMLBlob = (char *) calloc(1, aRange.length + 1); CFDataGetBytes( inMappings, aRange, (UInt8*)ourXMLBlob ); //now attempt to create the record here //if it already exists then simply modify the attribute ouvals[0] = "macosxodconfig"; ouvals[1] = NULL; oumod.mod_op = 0; oumod.mod_type = "ou"; oumod.mod_values = ouvals; mapvals[0] = ourXMLBlob; mapvals[1] = NULL; mapmod.mod_op = 0; mapmod.mod_type = "description"; mapmod.mod_values = mapvals; ocvals[0] = "top"; ocvals[1] = "organizationalUnit"; ocvals[2] = NULL; ocmod.mod_op = 0; ocmod.mod_type = "objectclass"; ocmod.mod_values = ocvals; mods[0] = &oumod; mods[1] = &mapmod; mods[2] = &ocmod; mods[3] = NULL; ldapReturnCode = 0; siResult = eDSNoErr; ldapReturnCode = ldap_add_s( serverHost, ldapDNString, mods); if ( ( ldapReturnCode == LDAP_INSUFFICIENT_ACCESS ) || ( ldapReturnCode == LDAP_INVALID_CREDENTIALS ) ) { siResult = eDSPermissionError; } else if ( ldapReturnCode == LDAP_ALREADY_EXISTS ) { siResult = eDSRecordAlreadyExists; } else if ( ldapReturnCode == LDAP_NO_SUCH_OBJECT ) { siResult = eDSRecordNotFound; } else if ( ldapReturnCode != LDAP_SUCCESS ) { siResult = eDSBogusServer; } } //if ( (siResult == eDSRecordNotFound) || (siResult == eDSNoErr) ) } // if ( (serverHost != nil) && (mapSearchBase != nil) ) } // inMappings != nil } // try catch ( sInt32 err ) { siResult = err; if (configPropertyList != nil) { CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; } } if ( serverHost != nil ) { ldap_unbind( serverHost ); serverHost = nil; } if ( mapSearchBase != nil ) { free( mapSearchBase ); mapSearchBase = nil; } if ( ourXMLBlob != nil ) { free( ourXMLBlob ); ourXMLBlob = nil; } if ( ldapDNString != nil ) { free( ldapDNString ); ldapDNString = nil; } return( siResult ); } // WriteServerMappings //------------------------------------------------------------------------------------ // * ReadServerMappings //------------------------------------------------------------------------------------ CFDataRef CLDAPv3Configs::ReadServerMappings ( LDAP *serverHost, CFDataRef inMappings ) { sInt32 siResult = eDSNoErr; CFStringRef errorString; CFPropertyListRef configPropertyList = nil; CFMutableDictionaryRef serverConfigDict = nil; char *configVersion = nil; char *tmpBuff = nil; CFIndex cfBuffSize = 1024; CFStringRef cfStringRef = nil; CFBooleanRef cfBool = false; char *mapSearchBase = nil; bool bIsSSL = false; bool bServerMappings = false; bool bUseConfig = false; unsigned char cfNumBool = false; CFNumberRef cfNumber = 0; char *server = nil; int portNumber = 389; CFDataRef outMappings = nil; //takes in the partial XML config blob and extracts the mappings out of the server to return the true XML config blob try { if (inMappings != nil) { // extract the config dictionary from the XML data. configPropertyList = CFPropertyListCreateFromXMLData( kAllocatorDefault, inMappings, kCFPropertyListImmutable, //could also use kCFPropertyListImmutable, kCFPropertyListMutableContainers &errorString); if (configPropertyList != nil ) { //make the propertylist a dict if ( CFDictionaryGetTypeID() == CFGetTypeID( configPropertyList ) ) { serverConfigDict = (CFMutableDictionaryRef) configPropertyList; //don't need mutable really } if (serverConfigDict != nil) { //config data version configVersion = GetVersion(serverConfigDict); //TODO KW check for correct version? not necessary really since backward compatible? if ( configVersion == nil ) throw( (sInt32)eDSVersionMismatch ); //KW need eDSPlugInConfigFileError if (configVersion != nil) { if (strcmp(configVersion,"DSLDAPv3PlugIn Version 1.5") == 0) { //get relevant parameters out of dict if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLEnableUseFlagKey ) ) ) { //KW assume that the extracted strings will be significantly less than 1024 characters tmpBuff = (char *)::calloc(1, 1024); cfBool = (CFBooleanRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLEnableUseFlagKey ) ); if (cfBool != nil) { bUseConfig = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get } //continue if this configuration was enabled by the user //no error condition returned if this configuration is not used due to the enable use flag if ( bUseConfig ) { if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLServerMappingsFlagKey ) ) ) { cfBool = (CFBooleanRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLServerMappingsFlagKey ) ); if (cfBool != nil) { bServerMappings = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get } } if (bServerMappings) { // retrieve all the relevant values (server, portNumber, mapsearchbase, IsSSL) // to enable server mapping write if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLServerKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLServerKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { server = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(server, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLIsSSLFlagKey ) ) ) { cfBool= (CFBooleanRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLIsSSLFlagKey ) ); if (cfBool != nil) { bIsSSL = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get if (bIsSSL) { portNumber = 636; // default for SSL ie. if no port given below } } } if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLPortNumberKey ) ) ) { cfNumber = (CFNumberRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLPortNumberKey ) ); if ( cfNumber != nil ) { cfNumBool = CFNumberGetValue(cfNumber, kCFNumberIntType, &portNumber); //CFRelease(cfNumber); // no since pointer only from Get } } if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLMapSearchBase ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLMapSearchBase ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { mapSearchBase = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(mapSearchBase, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } } }// if ( bUseConfig ) //free up the tmpBuff free( tmpBuff ); tmpBuff = nil; }// if kXMLEnableUseFlagKey set } free( configVersion ); configVersion = nil; }//if (configVersion != nil) // don't release the serverConfigDict since it is the cast configPropertyList }//if (serverConfigDict != nil) CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; }//if (configPropertyList != nil ) outMappings = RetrieveServerMappings( server, mapSearchBase, portNumber, bIsSSL ); } // inMappings != nil } // try catch ( sInt32 err ) { siResult = err; if (configPropertyList != nil) { CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; } } if ( server != nil ) { free( server ); server = nil; } if ( mapSearchBase != nil ) { free( mapSearchBase ); mapSearchBase = nil; } return( outMappings ); } // ReadServerMappings // --------------------------------------------------------------------------- // * VerifyAndUpdateServerLocation // --------------------------------------------------------------------------- CFDataRef CLDAPv3Configs::VerifyAndUpdateServerLocation( char *inServer, int inPortNumber, bool inIsSSL, CFDataRef inXMLData ) { CFStringRef errorString = nil; CFPropertyListRef configPropertyList = nil; CFMutableDictionaryRef serverConfigDict = nil; char *configVersion = nil; char *server = nil; int portNumber = 389; bool bIsSSL = false; char *tmpBuff = nil; CFStringRef cfStringRef = nil; bool bUpdate = false; CFBooleanRef cfBool = false; CFNumberRef cfNumber = 0; CFIndex cfBuffSize = 1024; unsigned char cfNumBool = false; CFDataRef outXMLData = nil; if (inXMLData != nil) { // extract the config dictionary from the XML data. configPropertyList = CFPropertyListCreateFromXMLData( kAllocatorDefault, inXMLData, kCFPropertyListMutableContainers, //could also use kCFPropertyListImmutable, kCFPropertyListImmutable &errorString); if (configPropertyList != nil ) { //make the propertylist a dict if ( CFDictionaryGetTypeID() == CFGetTypeID( configPropertyList ) ) { serverConfigDict = (CFMutableDictionaryRef) configPropertyList; //don't need mutable really } if (serverConfigDict != nil) { //get version, and the specific LDAP server config //config data version configVersion = GetVersion(serverConfigDict); //bail out of checking in this routine if ( configVersion == nil ) { CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; return nil; } else { CShared::LogIt( 0x0F, (char *)"Have successfully read the LDAP XML config data" ); //if config data is up to date with latest default mappings then use them if (strcmp(configVersion,"DSLDAPv3PlugIn Version 1.5") == 0) { //now verify the inServer, inPortNumber and inIsSSL if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLServerKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLServerKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { //KW assume that the extracted strings will be significantly less than 1024 characters tmpBuff = (char *)::calloc(1, 1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { server = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(server, tmpBuff); if (strcmp(server,inServer) != 0) { //replace the server value bUpdate = true; cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, inServer, kCFStringEncodingUTF8); CFDictionaryReplaceValue(serverConfigDict, CFSTR( kXMLServerKey ), cfStringRef); CFRelease(cfStringRef); cfStringRef = nil; } free(server); server = nil; } free(tmpBuff); tmpBuff = nil; } //CFRelease(cfStringRef); // no since pointer only from Get } } if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLPortNumberKey ) ) ) { cfNumber = (CFNumberRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLPortNumberKey ) ); if ( cfNumber != nil ) { cfNumBool = CFNumberGetValue(cfNumber, kCFNumberIntType, &portNumber); if (portNumber != inPortNumber) { //replace the port number bUpdate = true; cfNumber = CFNumberCreate(NULL,kCFNumberIntType,&inPortNumber); CFDictionaryReplaceValue(serverConfigDict, CFSTR( kXMLPortNumberKey ), cfNumber); CFRelease(cfNumber); cfNumber = 0; } //CFRelease(cfNumber); // no since pointer only from Get } } if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLIsSSLFlagKey ) ) ) { cfBool= (CFBooleanRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLIsSSLFlagKey ) ); if (cfBool != nil) { bIsSSL = CFBooleanGetValue( cfBool ); if (bIsSSL != inIsSSL) { //replace the SSL flag bUpdate = true; if (inIsSSL) { cfBool = kCFBooleanTrue; } else { cfBool = kCFBooleanFalse; } CFDictionaryReplaceValue(serverConfigDict, CFSTR( kXMLIsSSLFlagKey ), cfBool); } //CFRelease( cfBool ); // no since pointer only from Get } } if ( CFDictionaryContainsKey( serverConfigDict, CFSTR( kXMLMakeDefLDAPFlagKey ) ) ) { cfBool = (CFBooleanRef)CFDictionaryGetValue( serverConfigDict, CFSTR( kXMLMakeDefLDAPFlagKey ) ); if (cfBool == kCFBooleanFalse) { bUpdate = true; CFDictionaryReplaceValue(serverConfigDict, CFSTR( kXMLMakeDefLDAPFlagKey ), kCFBooleanTrue); } } else { bUpdate = true; CFDictionarySetValue(serverConfigDict, CFSTR( kXMLMakeDefLDAPFlagKey ), kCFBooleanTrue); } if (bUpdate) { //create a new XML blob outXMLData = CFPropertyListCreateXMLData( kCFAllocatorDefault, serverConfigDict); } } delete(configVersion); }//if (configVersion != nil) // don't release the serverConfigDict since it is the cast configPropertyList }//if (serverConfigDict != nil) CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; }//if (configPropertyList != nil ) } // inXMLData != nil return( outXMLData ); } // VerifyAndUpdateServerLocation // --------------------------------------------------------------------------- // * AddDefaultLDAPServer // --------------------------------------------------------------------------- sInt32 CLDAPv3Configs::AddDefaultLDAPServer( CFDataRef inXMLData ) { sInt32 siResult = eDSNoErr; CFStringRef errorString = nil; CFPropertyListRef configPropertyList = nil; CFMutableDictionaryRef serverConfigDict = nil; char *configVersion = nil; try { if (inXMLData != nil) { // extract the config dictionary from the XML data. configPropertyList = CFPropertyListCreateFromXMLData( kAllocatorDefault, inXMLData, kCFPropertyListImmutable, //could also use kCFPropertyListImmutable, kCFPropertyListMutableContainers &errorString); if (configPropertyList != nil ) { //make the propertylist a dict if ( CFDictionaryGetTypeID() == CFGetTypeID( configPropertyList ) ) { serverConfigDict = (CFMutableDictionaryRef) configPropertyList; //don't need mutable really } if (serverConfigDict != nil) { //get version, and the specific LDAP server config //config data version configVersion = GetVersion(serverConfigDict); //TODO KW check for correct version? not necessary really since backward compatible? if ( configVersion == nil ) { syslog(LOG_INFO,"DSLDAPv3PlugIn: DHCP option 95 obtained LDAP server mappings is missing the version string."); throw( (sInt32)eDSVersionMismatch ); //KW need eDSPlugInConfigFileError } if (configVersion != nil) { CShared::LogIt( 0x0F, (char *)"Have successfully read the LDAP XML config data" ); //if config data is up to date with latest default mappings then use them if (strcmp(configVersion,"DSLDAPv3PlugIn Version 1.5") == 0) { siResult = MakeLDAPConfig(serverConfigDict, fConfigTableLen); } else { syslog(LOG_INFO,"DSLDAPv3PlugIn: DHCP option 95 obtained LDAP server mappings contains incorrect version string [%s] instead of [DSLDAPv3PlugIn Version 1.5].", configVersion); } delete(configVersion); }//if (configVersion != nil) // don't release the serverConfigDict since it is the cast configPropertyList }//if (serverConfigDict != nil) CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; }//if (configPropertyList != nil ) } // fXMLData != nil } // try catch ( sInt32 err ) { siResult = err; if (configPropertyList != nil) { CFRelease(configPropertyList); // built from Create on XML data so okay to dealloc here configPropertyList = nil; } } return( siResult ); } // AddDefaultLDAPServer // -------------------------------------------------------------------------------- // * CheckForServerMappings // -------------------------------------------------------------------------------- CFDictionaryRef CLDAPv3Configs::CheckForServerMappings ( CFDictionaryRef ldapDict ) { char *tmpBuff = nil; CFIndex cfBuffSize = 1024; CFStringRef cfStringRef = nil; CFBooleanRef cfBool = false; unsigned char cfNumBool = false; CFNumberRef cfNumber = 0; char *server = nil; char *mapSearchBase = nil; int portNumber = 389; bool bIsSSL = false; bool bServerMappings = false; bool bUseConfig = false; CFDictionaryRef outDict = nil; CFStringRef errorString; if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLEnableUseFlagKey ) ) ) { //KW assume that the extracted strings will be significantly less than 1024 characters tmpBuff = (char *)::calloc(1, 1024); cfBool = (CFBooleanRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLEnableUseFlagKey ) ); if (cfBool != nil) { bUseConfig = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get } //continue if this configuration was enabled by the user //no error condition returned if this configuration is not used due to the enable use flag if ( bUseConfig ) { if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLServerMappingsFlagKey ) ) ) { cfBool = (CFBooleanRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLServerMappingsFlagKey ) ); if (cfBool != nil) { bServerMappings = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get } } if (bServerMappings) { //retrieve all the relevant values (servername, mapsearchbase, portnumber, IsSSL) to enable server mapping retrieval if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLServerKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLServerKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { server = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(server, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLIsSSLFlagKey ) ) ) { cfBool= (CFBooleanRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLIsSSLFlagKey ) ); if (cfBool != nil) { bIsSSL = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get if (bIsSSL) { portNumber = 636; // default for SSL ie. if no port given below } } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLPortNumberKey ) ) ) { cfNumber = (CFNumberRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLPortNumberKey ) ); if ( cfNumber != nil ) { cfNumBool = CFNumberGetValue(cfNumber, kCFNumberIntType, &portNumber); //CFRelease(cfNumber); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLMapSearchBase ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLMapSearchBase ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { mapSearchBase = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(mapSearchBase, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } CFDataRef ourXMLData = nil; ourXMLData = RetrieveServerMappings( server, mapSearchBase, portNumber, bIsSSL ); if (ourXMLData != nil) { CFPropertyListRef configPropertyList = nil; // extract the config dictionary from the XML data. configPropertyList = CFPropertyListCreateFromXMLData( kAllocatorDefault, ourXMLData, kCFPropertyListImmutable, //could also use kCFPropertyListImmutable, kCFPropertyListMutableContainers &errorString); if (configPropertyList != nil ) { //make the propertylist a dict if ( CFDictionaryGetTypeID() == CFGetTypeID( configPropertyList ) ) { outDict = (CFDictionaryRef) configPropertyList; } }//if (configPropertyList != nil ) CFRelease(ourXMLData); ourXMLData = nil; } } if ( server != nil ) { free( server ); server = nil; } if ( mapSearchBase != nil ) { free( mapSearchBase ); mapSearchBase = nil; } }// if ( bUseConfig ) //free up the tmpBuff delete( tmpBuff ); }// if kXMLEnableUseFlagKey set // return if nil or not return( outDict ); } // CheckForServerMappings // -------------------------------------------------------------------------------- // * MakeLDAPConfig // -------------------------------------------------------------------------------- sInt32 CLDAPv3Configs::MakeLDAPConfig ( CFDictionaryRef ldapDict, sInt32 inIndex ) { sInt32 siResult = eDSNoErr; char *tmpBuff = nil; CFIndex cfBuffSize = 1024; // char *outVersion = nil; CFStringRef cfStringRef = nil; CFDataRef cfDataRef = nil; CFBooleanRef cfBool = false; unsigned char cfNumBool = false; CFNumberRef cfNumber = 0; char *uiName = nil; char *server = nil; char *account = nil; char *password = nil; int passwordLen = 0; int opencloseTO = 0; int searchTO = 0; int portNumber = 389; bool bIsSSL = false; bool bServerMappings = false; bool bMakeDefLDAP= false; bool bUseStdMap = false; bool bUseSecure = false; bool bUseConfig = false; sLDAPConfigData *pConfig = nil; sLDAPConfigData *xConfig = nil; uInt32 serverIndex = 0; bool reuseEntry = false; if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLEnableUseFlagKey ) ) ) { //KW assume that the extracted strings will be significantly less than 1024 characters tmpBuff = (char *)::calloc(1, 1024); cfBool = (CFBooleanRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLEnableUseFlagKey ) ); if (cfBool != nil) { bUseConfig = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get } //continue if this configuration was enabled by the user //no error condition returned if this configuration is not used due to the enable use flag if ( bUseConfig ) { //need to get the server name first if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLServerKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLServerKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { server = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(server, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } //KW Need to check here if the config already exists ie. the server name exists //if it does then assume that this will replace what was given before if (CheckForConfig(server, serverIndex)) { reuseEntry = true; xConfig = (sLDAPConfigData *)pConfigTable->GetItemData( serverIndex ); if (xConfig != nil) { // delete the contents of sLDAPConfigData here // not checking the return status of the clean here // since we know xConfig is NOT nil going in CleanLDAPConfigData( xConfig ); // delete the sLDAPConfigData itself delete( xConfig ); xConfig = nil; // remove the table entry pConfigTable->RemoveItem( serverIndex ); } } //Enable Use flag is NOT provided to the configTable //retrieve all the others for the configTable if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLIsSSLFlagKey ) ) ) { cfBool= (CFBooleanRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLIsSSLFlagKey ) ); if (cfBool != nil) { bIsSSL = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get if (bIsSSL) { portNumber = 636; // default for SSL ie. if no port given below } } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLPortNumberKey ) ) ) { cfNumber = (CFNumberRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLPortNumberKey ) ); if ( cfNumber != nil ) { cfNumBool = CFNumberGetValue(cfNumber, kCFNumberIntType, &portNumber); //CFRelease(cfNumber); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLServerMappingsFlagKey ) ) ) { cfBool = (CFBooleanRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLServerMappingsFlagKey ) ); if (cfBool != nil) { bServerMappings = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLOpenCloseTimeoutSecsKey ) ) ) { cfNumber = (CFNumberRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLOpenCloseTimeoutSecsKey ) ); if ( cfNumber != nil ) { cfNumBool = CFNumberGetValue(cfNumber, kCFNumberIntType, &opencloseTO); //CFRelease(cfNumber); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLSearchTimeoutSecsKey ) ) ) { cfNumber = (CFNumberRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLSearchTimeoutSecsKey ) ); if ( cfNumber != nil ) { cfNumBool = CFNumberGetValue(cfNumber, kCFNumberIntType, &searchTO); //CFRelease(cfNumber); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLSecureUseFlagKey ) ) ) { cfBool= (CFBooleanRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLSecureUseFlagKey ) ); if (cfBool != nil) { bUseSecure = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get } } //null strings are acceptable but not preferred //ie. the new char will be of length one and the strcpy will copy the "" - empty string if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLUserDefinedNameKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLUserDefinedNameKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { uiName = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(uiName, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLServerAccountKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLServerAccountKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { account = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(account, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLServerPasswordKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLServerPasswordKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFDataGetTypeID() ) { cfDataRef = (CFDataRef)cfStringRef; passwordLen = CFDataGetLength(cfDataRef); password = (char*)::calloc(1+passwordLen,1); CFDataGetBytes(cfDataRef, CFRangeMake(0,passwordLen), (UInt8*)password); } else if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { password = (char *)::calloc(1+strlen(tmpBuff),1); ::strcpy(password, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLStdMapUseFlagKey ) ) ) { cfBool = (CFBooleanRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLStdMapUseFlagKey ) ); if (cfBool != nil) { bUseStdMap = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get } } if ( CFDictionaryContainsKey( ldapDict, CFSTR( kXMLMakeDefLDAPFlagKey ) ) ) { cfBool = (CFBooleanRef)CFDictionaryGetValue( ldapDict, CFSTR( kXMLMakeDefLDAPFlagKey ) ); if (cfBool != nil) { bMakeDefLDAP = CFBooleanGetValue( cfBool ); //CFRelease( cfBool ); // no since pointer only from Get } } //setup the config table // MakeLDAPConfigData does not consume the strings passed in so we need to free them below pConfig = MakeLDAPConfigData( uiName, server, bUseStdMap, opencloseTO, searchTO, portNumber, bUseSecure, account, password, bMakeDefLDAP, bServerMappings, bIsSSL ); if (!bUseStdMap) //TODO bUseStdMap will be replaced with templates { //get the mappings from the config ldap dict BuildLDAPMap( pConfig, ldapDict ); } if ( uiName != nil ) { free( uiName ); uiName = nil; } if ( server != nil ) { free( server ); server = nil; } if ( account != nil ) { free( account ); account = nil; } if ( password != nil ) { free( password ); password = nil; } if (reuseEntry) { pConfigTable->AddItem( serverIndex, pConfig ); } else { pConfigTable->AddItem( inIndex, pConfig ); fConfigTableLen++; } }// if ( bUseConfig ) //free up the tmpBuff delete( tmpBuff ); }// if kXMLEnableUseFlagKey set // return if nil or not return( siResult ); } // MakeLDAPConfig // -------------------------------------------------------------------------------- // * CheckForConfig // -------------------------------------------------------------------------------- bool CLDAPv3Configs::CheckForConfig ( char *inServerName, uInt32 &inConfigTableIndex ) { bool result = false; uInt32 iTableIndex = 0; sLDAPConfigData *pConfig = nil; if (inServerName != nil) { //need to cycle through the config table for (iTableIndex=0; iTableIndexGetItemData( iTableIndex ); if (pConfig != nil) { if (pConfig->fServerName != nil) { if (::strcmp(pConfig->fServerName, inServerName) == 0 ) { result = true; inConfigTableIndex = iTableIndex; break; } } } } } return(result); } // CheckForConfig // -------------------------------------------------------------------------------- // * BuildLDAPMap // -------------------------------------------------------------------------------- sInt32 CLDAPv3Configs::BuildLDAPMap ( sLDAPConfigData *inConfig, CFDictionaryRef ldapDict ) { sInt32 siResult = eDSNoErr; // used for? CFArrayRef cfArrayRef = nil; // sMapTuple *pRecMapTuple = nil; // sMapTuple *pAttrMapTuple = nil; cfArrayRef = nil; cfArrayRef = GetRecordTypeMapArray(ldapDict); if (cfArrayRef != nil) { inConfig->fRecordTypeMapCFArray = CFArrayCreateCopy(kCFAllocatorDefault, cfArrayRef); } cfArrayRef = nil; cfArrayRef = GetAttributeTypeMapArray(ldapDict); if (cfArrayRef != nil) { inConfig->fAttrTypeMapCFArray = CFArrayCreateCopy(kCFAllocatorDefault, cfArrayRef); } /* pRecMapTuple = BuildMapTuple(cfArrayRef); pAttrMapTuple = BuildMapTuple(cfArrayRef); if (pRecMapTuple != nil) { inConfig->pRecordMapTuple = pRecMapTuple; } else { inConfig->pRecordMapTuple = pStdRecordMapTuple; } if (pAttrMapTuple != nil) { inConfig->pAttributeMapTuple = pAttrMapTuple; } else { inConfig->pAttributeMapTuple = pStdAttributeMapTuple; } */ return( siResult ); } // BuildLDAPMap // -------------------------------------------------------------------------------- // * BuildMapTuple // -------------------------------------------------------------------------------- sMapTuple *CLDAPv3Configs::BuildMapTuple ( CFArrayRef inArray ) { CFArrayRef cfArrayRef = nil; CFIndex cfMapCount = 0; CFIndex cfNativeMapCount = 0; CFIndex cfSubNativeMapCount = 0; sInt32 iMapIndex = 0; sInt32 iNativeMapIndex = 0; sInt32 iSubNativeMapIndex = 0; bool bUseMap = false; CFStringRef cfStringRef = nil; char *tmpBuff = nil; CFIndex cfBuffSize = 1024; char *stdMapType = nil; char *nativeMapType = nil; CFArrayRef cfNativeArrayRef = nil; sMapTuple *pMapTuple = nil; sMapTuple *currentMapTuple = nil; sPtrString *currentNativeMap = nil; sPtrString *currentSubNativeMap = nil; sInt32 siResult = eDSNoErr; char *objectClass = nil; cfArrayRef = inArray; if (cfArrayRef != nil) { //now we can retrieve each Type mapping cfMapCount = ::CFArrayGetCount( cfArrayRef ); if (cfMapCount != 0) { //KW assume that the extracted strings will be significantly less than 1024 characters tmpBuff = (char *) calloc(1, 1024); // tmpBuff = new char[1024]; // ::memset(tmpBuff,0,1024); //loop through the maps for (iMapIndex = 0; iMapIndex < cfMapCount; iMapIndex++) { CFDictionaryRef typeMapDict; typeMapDict = (CFDictionaryRef)::CFArrayGetValueAtIndex( cfArrayRef, iMapIndex ); if ( typeMapDict != nil ) { //KW retrieve the mappings // get the standard type label first if ( CFDictionaryContainsKey( typeMapDict, CFSTR( kXMLStdNameKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( typeMapDict, CFSTR( kXMLStdNameKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { stdMapType = new char[1+strlen(tmpBuff)]; ::strcpy(stdMapType, tmpBuff); } } //CFRelease(cfStringRef); // no since pointer only from Get } } // get the native map array of labels next cfNativeArrayRef = nil; cfNativeArrayRef = GetNativeTypeMapArray(typeMapDict); //now we need to determine for each array entry whether it is a string(searchbase) //or a dictionary(objectclass and searchbase) if (cfNativeArrayRef != nil) { //now we can retrieve each Native Type mapping to the given Standard type cfNativeMapCount = ::CFArrayGetCount( cfNativeArrayRef ); //check here that we have a potential entry //ie. std type not nil and an entry in the native map array if ((cfNativeMapCount != 0) && (stdMapType != nil)) { //create the mapping entry if (pMapTuple == nil) { pMapTuple = new sMapTuple; currentMapTuple = pMapTuple; } else { currentMapTuple->pNext = new sMapTuple; currentMapTuple = currentMapTuple->pNext; } if ( currentMapTuple != nil ) { ::memset( currentMapTuple, 0, sizeof( sMapTuple ) ); currentMapTuple->fStandard = stdMapType; currentMapTuple->pNext = nil; } //loop through the Native Maps for (iNativeMapIndex = 0; iNativeMapIndex < cfNativeMapCount; iNativeMapIndex++) { //determine whether the array entry is a string or an array if (CFGetTypeID(CFArrayGetValueAtIndex( cfNativeArrayRef, iNativeMapIndex )) == CFStringGetTypeID()) { CFStringRef nativeMapString; nativeMapString = (CFStringRef)::CFArrayGetValueAtIndex( cfNativeArrayRef, iNativeMapIndex ); if ( nativeMapString != nil ) { if ( CFGetTypeID( nativeMapString ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(nativeMapString, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { nativeMapType = new char[1+strlen(tmpBuff)]; ::strcpy(nativeMapType, tmpBuff); //add to the mapping with a native entry if (currentMapTuple->fNative == nil) { currentMapTuple->fNative = new sPtrString; currentNativeMap = currentMapTuple->fNative; } else { currentNativeMap->pNext = new sPtrString; currentNativeMap = currentNativeMap->pNext; } if ( currentNativeMap != nil ) { ::memset( currentNativeMap, 0, sizeof( sPtrString ) ); currentNativeMap->fName = nativeMapType; currentNativeMap->pNext = nil; //at least one map is valid so set to true and use it bUseMap = true; } } } //CFRelease(nativeMapString); // no since pointer only from Get }// if ( nativeMapString != nil ) }// array entry is a string ie. no ObjectClasses else //assume this is a dict since not a string { CFDictionaryRef subNativeDict; subNativeDict = (CFDictionaryRef)CFArrayGetValueAtIndex( cfNativeArrayRef, iNativeMapIndex ); if (subNativeDict != nil) { if ( CFGetTypeID( subNativeDict ) == CFDictionaryGetTypeID() ) { CFStringRef searchBase; searchBase = (CFStringRef)CFDictionaryGetValue( subNativeDict, CFSTR( kXMLSearchBase ) ); if (searchBase != nil) { if ( CFGetTypeID( searchBase ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(searchBase, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { nativeMapType = new char[1+strlen(tmpBuff)]; ::strcpy(nativeMapType, tmpBuff); //add to the mapping with a native entry if (currentMapTuple->fNative == nil) { currentMapTuple->fNative = new sPtrString; currentNativeMap = currentMapTuple->fNative; } else { currentNativeMap->pNext = new sPtrString; currentNativeMap = currentNativeMap->pNext; } if ( currentNativeMap != nil ) { ::memset( currentNativeMap, 0, sizeof( sPtrString ) ); currentNativeMap->fName = nativeMapType; currentNativeMap->pNext = nil; //at least one map is valid so set to true and use it bUseMap = true; //now deal with the objectclass entries if appropriate CFArrayRef objectClasses; objectClasses = (CFArrayRef)CFDictionaryGetValue( subNativeDict, CFSTR( kXMLObjectClasses ) ); if (objectClasses != nil) { if ( CFGetTypeID( objectClasses ) == CFArrayGetTypeID() ) { CFStringRef groupOCString = nil; groupOCString = (CFStringRef)CFDictionaryGetValue( subNativeDict, CFSTR( kXMLGroupObjectClasses ) ); if ( groupOCString != nil ) { if ( CFGetTypeID( groupOCString ) == CFStringGetTypeID() ) { if (CFStringCompare( groupOCString, CFSTR("AND"), 0 ) == kCFCompareEqualTo) { currentNativeMap->fGroupSubNative = 0; } else { currentNativeMap->fGroupSubNative = 1; } } } cfSubNativeMapCount = ::CFArrayGetCount( objectClasses ); //loop through the object classes for (iSubNativeMapIndex = 0; iSubNativeMapIndex < cfSubNativeMapCount; iSubNativeMapIndex++) { CFStringRef objectClassString = nil; objectClassString = (CFStringRef)::CFArrayGetValueAtIndex( objectClasses, iSubNativeMapIndex ); if ( objectClassString != nil ) { if ( CFGetTypeID( objectClassString ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(objectClassString, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { objectClass = new char[1+strlen(tmpBuff)]; ::strcpy(objectClass, tmpBuff); //add to the mapping with a native entry if (currentNativeMap->fSubNative == nil) { currentNativeMap->fSubNative = new sPtrString; currentSubNativeMap = currentNativeMap->fSubNative; } else { currentSubNativeMap->pNext = new sPtrString; currentSubNativeMap = currentSubNativeMap->pNext; } if ( currentSubNativeMap != nil ) { ::memset( currentSubNativeMap, 0, sizeof( sPtrString ) ); currentSubNativeMap->fName = objectClass; currentSubNativeMap->pNext = nil; } }// if (CFStringGetCString(searchBase, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) }// if ( CFGetTypeID( objectClassString ) == CFStringGetTypeID() ) }// if ( objectClassString != nil ) }// for (iSubNativeMapIndex = 0; iSubNativeMapIndex < cfSubNativeMapCount; iSubNativeMapIndex++) }// if ( CFGetTypeID( objectClasses ) == CFArrayGetTypeID() ) }// if (objectClasses != nil) }// if ( currentNativeMap != nil ) }// if (CFStringGetCString(searchBase, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) }// if ( CFGetTypeID( searchBase ) == CFStringGetTypeID() ) } } } } }//loop through the Native Maps }// if (cfNativeMapCount != 0) else if (stdMapType != nil) { // we should free this since we didn't consume it free( stdMapType ); stdMapType = nil; } }// if (cfNativeArrayRef != nil) //CFRelease( typeMapDict ); // no since pointer only from Get }//if ( typeMapDict != nil ) } // loop over maps delete( tmpBuff ); } // if (cfMapCount != 0) } // if (cfArrayRef != nil) ie. an array of Record Maps exists if (!bUseMap) { siResult = CleanMapTuple(pMapTuple); } return( pMapTuple ); } // BuildMapTuple // -------------------------------------------------------------------------------- // * GetVersion // -------------------------------------------------------------------------------- char *CLDAPv3Configs::GetVersion ( CFDictionaryRef configDict ) { char *outVersion = nil; CFStringRef cfStringRef = nil; char *tmpBuff = nil; CFIndex cfBuffSize = 1024; if ( CFDictionaryContainsKey( configDict, CFSTR( kXMLLDAPVersionKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( configDict, CFSTR( kXMLLDAPVersionKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { //KW assume that the extracted strings will be significantly less than 1024 characters tmpBuff = new char[1024]; ::memset(tmpBuff,0,1024); if (CFStringGetCString(cfStringRef, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { outVersion = new char[1+strlen(tmpBuff)]; ::strcpy(outVersion, tmpBuff); } delete( tmpBuff ); } //CFRelease( cfStringRef ); // no since pointer only from Get } } // return if nil or not return( outVersion ); } // GetVersion // -------------------------------------------------------------------------------- // * GetConfigArray // -------------------------------------------------------------------------------- CFArrayRef CLDAPv3Configs::GetConfigArray ( CFDictionaryRef configDict ) { CFArrayRef cfArrayRef = nil; if ( CFDictionaryContainsKey( configDict, CFSTR( kXMLConfigArrayKey ) ) ) { cfArrayRef = (CFArrayRef)CFDictionaryGetValue( configDict, CFSTR( kXMLConfigArrayKey ) ); } // return if nil or not return( cfArrayRef ); } // GetConfigArray // -------------------------------------------------------------------------------- // * GetDefaultRecordTypeMapArray // -------------------------------------------------------------------------------- CFArrayRef CLDAPv3Configs::GetDefaultRecordTypeMapArray ( CFDictionaryRef configDict ) { CFArrayRef cfArrayRef = nil; if ( CFDictionaryContainsKey( configDict, CFSTR( kXMLDefaultRecordTypeMapArrayKey ) ) ) { cfArrayRef = (CFArrayRef)CFDictionaryGetValue( configDict, CFSTR( kXMLDefaultRecordTypeMapArrayKey ) ); } // return if nil or not return( cfArrayRef ); } // GetDefaultRecordTypeMapArray // -------------------------------------------------------------------------------- // * GetDefaultAttrTypeMapArray // -------------------------------------------------------------------------------- CFArrayRef CLDAPv3Configs::GetDefaultAttrTypeMapArray ( CFDictionaryRef configDict ) { CFArrayRef cfArrayRef = nil; if ( CFDictionaryContainsKey( configDict, CFSTR( kXMLDefaultAttrTypeMapArrayKey ) ) ) { cfArrayRef = (CFArrayRef)CFDictionaryGetValue( configDict, CFSTR( kXMLDefaultAttrTypeMapArrayKey ) ); } // return if nil or not return( cfArrayRef ); } // GetDefaultAttrTypeMapArray // -------------------------------------------------------------------------------- // * GetRecordTypeMapArray // -------------------------------------------------------------------------------- CFArrayRef CLDAPv3Configs::GetRecordTypeMapArray ( CFDictionaryRef configDict ) { CFArrayRef cfArrayRef = nil; if ( CFDictionaryContainsKey( configDict, CFSTR( kXMLRecordTypeMapArrayKey ) ) ) { cfArrayRef = (CFArrayRef)CFDictionaryGetValue( configDict, CFSTR( kXMLRecordTypeMapArrayKey ) ); } // return if nil or not return( cfArrayRef ); } // GetRecordTypeMapArray // -------------------------------------------------------------------------------- // * GetAttributeTypeMapArray // -------------------------------------------------------------------------------- CFArrayRef CLDAPv3Configs::GetAttributeTypeMapArray ( CFDictionaryRef configDict ) { CFArrayRef cfArrayRef = nil; if ( CFDictionaryContainsKey( configDict, CFSTR( kXMLAttrTypeMapArrayKey ) ) ) { cfArrayRef = (CFArrayRef)CFDictionaryGetValue( configDict, CFSTR( kXMLAttrTypeMapArrayKey ) ); } // return if nil or not return( cfArrayRef ); } // GetAttributeTypeMapArray // -------------------------------------------------------------------------------- // * GetNativeTypeMapArray // -------------------------------------------------------------------------------- CFArrayRef CLDAPv3Configs::GetNativeTypeMapArray ( CFDictionaryRef configDict ) { CFArrayRef cfArrayRef = nil; if ( CFDictionaryContainsKey( configDict, CFSTR( kXMLNativeMapArrayKey ) ) ) { cfArrayRef = (CFArrayRef)CFDictionaryGetValue( configDict, CFSTR( kXMLNativeMapArrayKey ) ); } // return if nil or not return( cfArrayRef ); } // GetNativeTypeMapArray // --------------------------------------------------------------------------- // * MakeLDAPConfigData // --------------------------------------------------------------------------- sLDAPConfigData *CLDAPv3Configs::MakeLDAPConfigData ( char *inName, char *inServerName, bool inUseStd, int inOpenCloseTO, int inSearchTO, int inPortNum, bool inUseSecure, char *inAccount, char *inPassword, bool inMakeDefLDAP, bool inServerMappings, bool inIsSSL ) { sInt32 siResult = eDSNoErr; sLDAPConfigData *configOut = nil; if (inServerName != nil) { configOut = new sLDAPConfigData; if ( configOut != nil ) { ::memset( configOut, 0, sizeof( sLDAPConfigData ) ); //do nothing with return here since we know this is new //and we did a memset above siResult = CleanLDAPConfigData(configOut); if (inName != nil) { configOut->fName = new char[1+::strlen( inName )]; ::strcpy(configOut->fName, inName); } configOut->fServerName = new char[1+::strlen( inServerName )]; ::strcpy(configOut->fServerName, inServerName); configOut->bUseStdMapping = inUseStd; configOut->fOpenCloseTimeout = inOpenCloseTO; configOut->fSearchTimeout = inSearchTO; configOut->fServerPort = inPortNum; configOut->bSecureUse = inUseSecure; configOut->bUpdated = true; configOut->bUseAsDefaultLDAP = inMakeDefLDAP; configOut->bServerMappings = inServerMappings; configOut->bIsSSL = inIsSSL; if (inAccount != nil) { configOut->fServerAccount = new char[1+::strlen( inAccount )]; ::strcpy(configOut->fServerAccount, inAccount); } if (inPassword != nil) { configOut->fServerPassword = new char[1+::strlen( inPassword )]; ::strcpy(configOut->fServerPassword, inPassword); } /* if (inUseStd) { configOut->pAttributeMapTuple = pStdAttributeMapTuple; configOut->pRecordMapTuple = pStdRecordMapTuple; } */ //TODO KW expect the default for the CFArray mapping to be a template configOut->fRecordTypeMapCFArray = 0; configOut->fAttrTypeMapCFArray = 0; } } // if (inServerName != nil) return( configOut ); } // MakeLDAPConfigData // --------------------------------------------------------------------------- // * CleanLDAPConfigData // --------------------------------------------------------------------------- sInt32 CLDAPv3Configs::CleanLDAPConfigData ( sLDAPConfigData *inConfig ) { sInt32 siResult = eDSNoErr; if ( inConfig == nil ) { siResult = eDSBadContextData; // KW want an eDSBadConfigData?? } else { if (inConfig->fName != nil) { delete ( inConfig->fName ); } if (inConfig->fServerName != nil) { delete ( inConfig->fServerName ); } if (inConfig->fServerAccount != nil) { delete ( inConfig->fServerAccount ); } if (inConfig->fServerPassword != nil) { delete ( inConfig->fServerPassword ); } inConfig->fName = nil; inConfig->fServerName = nil; inConfig->fServerAccount = nil; inConfig->fServerPassword = nil; //if (!(inConfig->bUseStdMapping)) //{ //CleanMapTuple(inConfig->pAttributeMapTuple); //CleanMapTuple(inConfig->pRecordMapTuple); //} if (inConfig->fRecordTypeMapCFArray != 0) { CFRelease(inConfig->fRecordTypeMapCFArray); inConfig->fRecordTypeMapCFArray = 0; } if (inConfig->fAttrTypeMapCFArray != 0) { CFRelease(inConfig->fAttrTypeMapCFArray); inConfig->fAttrTypeMapCFArray = 0; } inConfig->bUseStdMapping = true; inConfig->fOpenCloseTimeout = 120; inConfig->fSearchTimeout = 120; inConfig->fServerPort = 389; inConfig->bSecureUse = false; inConfig->bAvail = false; inConfig->bUpdated = false; inConfig->bUseAsDefaultLDAP = false; inConfig->bServerMappings = false; inConfig->bIsSSL = false; if (inConfig->fObjectClassSchema != nil) { inConfig->fObjectClassSchema->clear(); } } return( siResult ); } // CleanLDAPConfigData // --------------------------------------------------------------------------- // * ExtractRecMap // --------------------------------------------------------------------------- char* CLDAPv3Configs::ExtractRecMap( char *inRecType, CFArrayRef inRecordTypeMapCFArray, int inIndex, bool *outOCGroup, CFArrayRef *outOCListCFArray, ber_int_t* outScope ) { char *outResult = nil; CFIndex cfMapCount = 0; CFIndex cfNativeMapCount = 0; sInt32 iMapIndex = 0; CFStringRef cfStringRef = nil; CFStringRef cfRecTypeRef = nil; CFBooleanRef cfBoolRef = nil; char *tmpBuff = nil; CFIndex cfBuffSize = 1024; CFArrayRef cfNativeArrayRef = nil; if ( (inRecordTypeMapCFArray != nil) && (inRecType != nil) ) { cfRecTypeRef = CFStringCreateWithCString(kCFAllocatorDefault, inRecType, kCFStringEncodingUTF8); //now we can look for our Type mapping cfMapCount = ::CFArrayGetCount( inRecordTypeMapCFArray ); if (cfMapCount != 0) { //loop through the maps for (iMapIndex = 0; iMapIndex < cfMapCount; iMapIndex++) { CFDictionaryRef typeMapDict; typeMapDict = (CFDictionaryRef)::CFArrayGetValueAtIndex( inRecordTypeMapCFArray, iMapIndex ); if ( typeMapDict != nil ) { //retrieve the mappings // get the standard type label first if ( CFDictionaryContainsKey( typeMapDict, CFSTR( kXMLStdNameKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( typeMapDict, CFSTR( kXMLStdNameKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { if (CFStringCompare(cfStringRef, cfRecTypeRef, 0) == kCFCompareEqualTo) { // found the std mapping // get the native map array of labels next cfNativeArrayRef = GetNativeTypeMapArray(typeMapDict); //now we need to determine for each array entry whether it is a string(searchbase) //or a dictionary(objectclass and searchbase) if (cfNativeArrayRef != nil) { //now we can retrieve each Native Type mapping to the given Standard type cfNativeMapCount = ::CFArrayGetCount( cfNativeArrayRef ); //check here that we have a potential entry //ie. std type not nil and an entry in the native map array if (cfNativeMapCount != 0) { //get the inIndex 'th Native Map if ( (inIndex >= 1) && (inIndex <= cfNativeMapCount) ) { //assume that the std type extracted strings will be significantly less than 1024 characters tmpBuff = (char *) calloc(1, 1024); //determine whether the array entry is a string or a dictionary if (CFGetTypeID(CFArrayGetValueAtIndex( cfNativeArrayRef, inIndex-1 )) == CFStringGetTypeID()) { CFStringRef nativeMapString; nativeMapString = (CFStringRef)::CFArrayGetValueAtIndex( cfNativeArrayRef, inIndex-1 ); if ( nativeMapString != nil ) { if (CFStringGetCString(nativeMapString, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { outResult = (char *) calloc(1, 1+strlen(tmpBuff)); ::strcpy(outResult, tmpBuff); } //CFRelease(nativeMapString); // no since pointer only from Get }// if ( nativeMapString != nil ) if ( outScope != nil ) { *outScope = LDAP_SCOPE_SUBTREE; } }// array entry is a string ie. no ObjectClasses else //assume this is a dict since not a string { CFDictionaryRef subNativeDict; subNativeDict = (CFDictionaryRef)CFArrayGetValueAtIndex( cfNativeArrayRef, inIndex-1 ); if (subNativeDict != nil) { if ( CFGetTypeID( subNativeDict ) == CFDictionaryGetTypeID() ) { CFStringRef searchBase; searchBase = (CFStringRef)CFDictionaryGetValue( subNativeDict, CFSTR( kXMLSearchBase ) ); if (searchBase != nil) { if ( CFGetTypeID( searchBase ) == CFStringGetTypeID() ) { ::memset(tmpBuff,0,1024); if (CFStringGetCString(searchBase, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { outResult = (char *) calloc(1, 1+strlen(tmpBuff)); ::strcpy(outResult, tmpBuff); //now deal with the objectclass entries if appropriate CFArrayRef objectClasses; objectClasses = (CFArrayRef)CFDictionaryGetValue( subNativeDict, CFSTR( kXMLObjectClasses ) ); if ( (objectClasses != nil) && (outOCListCFArray != nil) && (outOCGroup != nil) ) { if ( CFGetTypeID( objectClasses ) == CFArrayGetTypeID() ) { *outOCGroup = 0; CFStringRef groupOCString = nil; groupOCString = (CFStringRef)CFDictionaryGetValue( subNativeDict, CFSTR( kXMLGroupObjectClasses ) ); if ( groupOCString != nil ) { if ( CFGetTypeID( groupOCString ) == CFStringGetTypeID() ) { if (CFStringCompare( groupOCString, CFSTR("AND"), 0 ) == kCFCompareEqualTo) { *outOCGroup = 1; } } } //make a copy of the CFArray of the objectClasses *outOCListCFArray = CFArrayCreateCopy(kCFAllocatorDefault, objectClasses); }// if ( CFGetTypeID( objectClasses ) == CFArrayGetTypeID() ) }// if (objectClasses != nil) }// if (CFStringGetCString(searchBase, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) }// if ( CFGetTypeID( searchBase ) == CFStringGetTypeID() ) } if (outScope != nil) { cfBoolRef = (CFBooleanRef)CFDictionaryGetValue( subNativeDict, CFSTR( kXMLOneLevelSearchScope ) ); if (cfBoolRef != nil) { if (CFBooleanGetValue(cfBoolRef)) { *outScope = LDAP_SCOPE_ONELEVEL; } else { *outScope = LDAP_SCOPE_SUBTREE; } } else { *outScope = LDAP_SCOPE_SUBTREE; } } } } } free(tmpBuff); }//get the correct indexed Native Map }// if (cfNativeMapCount != 0) }// if (cfNativeArrayRef != nil) //done so don't look for any more break; } } //CFRelease(cfStringRef); // no since pointer only from Get } } //CFRelease( typeMapDict ); // no since pointer only from Get }//if ( typeMapDict != nil ) } // loop over std rec maps - break above takes us out of this loop } // if (cfMapCount != 0) CFRelease(cfRecTypeRef); } // if (inRecordTypeMapCFArray != nil) ie. an array of Record Maps exists return( outResult ); } // ExtractRecMap // --------------------------------------------------------------------------- // * ExtractAttrMap // --------------------------------------------------------------------------- char* CLDAPv3Configs::ExtractAttrMap( char *inRecType, char *inAttrType, CFArrayRef inRecordTypeMapCFArray, CFArrayRef inAttrTypeMapCFArray, int inIndex ) { char *outResult = nil; CFIndex cfMapCount = 0; sInt32 iMapIndex = 0; CFStringRef cfStringRef = nil; CFStringRef cfRecTypeRef = nil; CFStringRef cfAttrTypeRef = nil; CFArrayRef cfAttrMapArrayRef = nil; bool bNoRecSpecificAttrMap = true; if ( (inRecordTypeMapCFArray != nil) && (inRecType != nil) && (inAttrType != nil) ) { cfRecTypeRef = CFStringCreateWithCString(kCFAllocatorDefault, inRecType, kCFStringEncodingUTF8); cfAttrTypeRef = CFStringCreateWithCString(kCFAllocatorDefault, inAttrType, kCFStringEncodingUTF8); //now we can look for our Type mapping cfMapCount = ::CFArrayGetCount( inRecordTypeMapCFArray ); if (cfMapCount != 0) { //loop through the maps for (iMapIndex = 0; iMapIndex < cfMapCount; iMapIndex++) { CFDictionaryRef typeMapDict; typeMapDict = (CFDictionaryRef)::CFArrayGetValueAtIndex( inRecordTypeMapCFArray, iMapIndex ); if ( typeMapDict != nil ) { //retrieve the mappings // get the standard type label first if ( CFDictionaryContainsKey( typeMapDict, CFSTR( kXMLStdNameKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( typeMapDict, CFSTR( kXMLStdNameKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { if (CFStringCompare(cfStringRef, cfRecTypeRef, 0) == kCFCompareEqualTo) { // found the std mapping // get the Attr map array for this std rec map cfAttrMapArrayRef = GetAttributeTypeMapArray(typeMapDict); outResult = ExtractAttrMapFromArray( cfAttrTypeRef, cfAttrMapArrayRef, inIndex, &bNoRecSpecificAttrMap ); if (bNoRecSpecificAttrMap) { //here we search the COMMON attr maps if std attr type not found above outResult = ExtractAttrMapFromArray( cfAttrTypeRef, inAttrTypeMapCFArray, inIndex, &bNoRecSpecificAttrMap ); //here don't care about the return of bNoRecSpecificAttrMap } //done so don't look for any more break; } } //CFRelease(cfStringRef); // no since pointer only from Get } } //CFRelease( typeMapDict ); // no since pointer only from Get }//if ( typeMapDict != nil ) } // loop over std rec maps - break above takes us out of this loop } // if (cfMapCount != 0) CFRelease(cfRecTypeRef); CFRelease(cfAttrTypeRef); } // if (inRecordTypeMapCFArray != nil) ie. an array of Record Maps exists return( outResult ); } // ExtractAttrMap // --------------------------------------------------------------------------- // * ExtractAttrMapFromArray // --------------------------------------------------------------------------- char* CLDAPv3Configs::ExtractAttrMapFromArray( CFStringRef inAttrTypeRef, CFArrayRef inAttrTypeMapCFArray, int inIndex, bool *bNoRecSpecificAttrMap ) { char *outResult = nil; CFIndex cfAttrMapCount = 0; CFIndex cfNativeMapCount = 0; sInt32 iAttrMapIndex = 0; CFStringRef cfAttrStringRef = nil; char *tmpBuff = nil; CFIndex cfBuffSize = 1024; CFArrayRef cfNativeMapArrayRef = nil; if ( (inAttrTypeRef != nil) && (inAttrTypeMapCFArray != nil) ) { //now we search for the inAttrType cfAttrMapCount = ::CFArrayGetCount( inAttrTypeMapCFArray ); //check here that we have a potential entry //ie. std type not nil and an entry in the native map array if (cfAttrMapCount != 0) { //loop through the Attr maps for (iAttrMapIndex = 0; iAttrMapIndex < cfAttrMapCount; iAttrMapIndex++) { CFDictionaryRef typeAttrMapDict; typeAttrMapDict = (CFDictionaryRef)::CFArrayGetValueAtIndex( inAttrTypeMapCFArray, iAttrMapIndex ); if ( typeAttrMapDict != nil ) { //retrieve the mappings // get the standard Attr type label first if ( CFDictionaryContainsKey( typeAttrMapDict, CFSTR( kXMLStdNameKey ) ) ) { cfAttrStringRef = (CFStringRef)CFDictionaryGetValue( typeAttrMapDict, CFSTR( kXMLStdNameKey ) ); if ( cfAttrStringRef != nil ) { if ( CFGetTypeID( cfAttrStringRef ) == CFStringGetTypeID() ) { if (CFStringCompare(cfAttrStringRef, inAttrTypeRef, 0) == kCFCompareEqualTo) { *bNoRecSpecificAttrMap = false; //found a rec type map specific attr map // found the std Attr mapping // get the native map array for this std Attr map cfNativeMapArrayRef = GetNativeTypeMapArray(typeAttrMapDict); if (cfNativeMapArrayRef != nil) { //now we search for the inAttrType cfNativeMapCount = ::CFArrayGetCount( cfNativeMapArrayRef ); if (cfNativeMapCount != 0) { //get the inIndex 'th Native Map if ( (inIndex >= 1) && (inIndex <= cfNativeMapCount) ) { //assume that the std type extracted strings will be significantly less than 1024 characters tmpBuff = (char *) calloc(1, 1024); //determine whether the array entry is a string if (CFGetTypeID(CFArrayGetValueAtIndex( cfNativeMapArrayRef, inIndex-1 )) == CFStringGetTypeID()) { CFStringRef nativeMapString; nativeMapString = (CFStringRef)::CFArrayGetValueAtIndex( cfNativeMapArrayRef, inIndex-1 ); if ( nativeMapString != nil ) { if (CFStringGetCString(nativeMapString, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { outResult = (char *) calloc(1, 1+strlen(tmpBuff)); ::strcpy(outResult, tmpBuff); } //CFRelease(nativeMapString); // no since pointer only from Get }// if ( nativeMapString != nil ) } free(tmpBuff); }//get the correct indexed Native Map }// (cfNativeMapCount != 0) }// if (cfNativeMapArrayRef != nil) //done so don't look for any more break; } } //CFRelease(cfAttrStringRef); // no since pointer only from Get } } //CFRelease( typeAttrMapDict ); // no since pointer only from Get }//if ( typeAttrMapDict != nil ) } //loop over the Attr maps }// if (cfAttrMapCount != 0) }// if (inAttrTypeMapCFArray != nil) return(outResult); } // ExtractAttrMapFromArray // --------------------------------------------------------------------------- // * ExtractStdAttr // --------------------------------------------------------------------------- char* CLDAPv3Configs::ExtractStdAttr( char *inRecType, CFArrayRef inRecordTypeMapCFArray, CFArrayRef inAttrTypeMapCFArray, int &inputIndex ) { char *outResult = nil; CFIndex cfMapCount = 0; CFIndex cfAttrMapCount = 0; CFIndex cfAttrMapCount2 = 0; sInt32 iMapIndex = 0; CFStringRef cfStringRef = nil; CFStringRef cfRecTypeRef = nil; CFArrayRef cfAttrMapArrayRef = nil; bool bUsedIndex = false; char *tmpBuff = nil; CFIndex cfBuffSize = 1024; int inIndex = inputIndex; if ( (inRecordTypeMapCFArray != nil) && (inRecType != nil) ) { cfRecTypeRef = CFStringCreateWithCString(kCFAllocatorDefault, inRecType, kCFStringEncodingUTF8); //now we can look for our Type mapping cfMapCount = ::CFArrayGetCount( inRecordTypeMapCFArray ); if (cfMapCount != 0) { //loop through the maps for (iMapIndex = 0; iMapIndex < cfMapCount; iMapIndex++) { CFDictionaryRef typeMapDict; typeMapDict = (CFDictionaryRef)::CFArrayGetValueAtIndex( inRecordTypeMapCFArray, iMapIndex ); if ( typeMapDict != nil ) { //retrieve the mappings // get the standard type label first if ( CFDictionaryContainsKey( typeMapDict, CFSTR( kXMLStdNameKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( typeMapDict, CFSTR( kXMLStdNameKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { if (CFStringCompare(cfStringRef, cfRecTypeRef, 0) == kCFCompareEqualTo) { // found the std mapping // get the Attr map array for this std rec map cfAttrMapArrayRef = GetAttributeTypeMapArray(typeMapDict); if (cfAttrMapArrayRef != nil) { cfAttrMapCount = ::CFArrayGetCount( cfAttrMapArrayRef ); if (cfAttrMapCount != 0) { //get the inIndex 'th Native Map if ( (inIndex >= 1) && (inIndex <= cfAttrMapCount) ) { bUsedIndex = true; //assume that the std type extracted strings will be significantly less than 1024 characters tmpBuff = (char *) calloc(1, 1024); //determine whether the array entry is a dict if (CFGetTypeID(CFArrayGetValueAtIndex( cfAttrMapArrayRef, inIndex-1 )) == CFDictionaryGetTypeID()) { CFDictionaryRef stdAttrTypeDict; stdAttrTypeDict = (CFDictionaryRef)CFArrayGetValueAtIndex( cfAttrMapArrayRef, inIndex-1 ); if ( stdAttrTypeDict != nil ) { if ( CFDictionaryContainsKey( stdAttrTypeDict, CFSTR( kXMLStdNameKey ) ) ) { CFStringRef attrMapString; attrMapString = (CFStringRef)CFDictionaryGetValue( stdAttrTypeDict, CFSTR( kXMLStdNameKey ) ); if ( attrMapString != nil ) { if (CFStringGetCString(attrMapString, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { outResult = (char *) calloc(1, 1+strlen(tmpBuff)); ::strcpy(outResult, tmpBuff); } //CFRelease(attrMapString); // no since pointer only from Get }// if ( attrMapString != nil ) } //std attr name present } //std attr type dict present } free(tmpBuff); }//get the correct indexed Native Map }// (cfAttrMapCount != 0) }// if (cfAttrMapArrayRef != nil) while (!bUsedIndex) { bUsedIndex = true; if (inAttrTypeMapCFArray != nil) { CFIndex commonIndex = inIndex - cfAttrMapCount; cfAttrMapCount2 = ::CFArrayGetCount( inAttrTypeMapCFArray ); if (cfAttrMapCount2 != 0) { //get the commonIndex 'th Native Map if ( (commonIndex >= 1) && (commonIndex <= cfAttrMapCount2) ) { //assume that the std type extracted strings will be significantly less than 1024 characters tmpBuff = (char *) calloc(1, 1024); //determine whether the array entry is a dict if (CFGetTypeID(CFArrayGetValueAtIndex( inAttrTypeMapCFArray, commonIndex-1 )) == CFDictionaryGetTypeID()) { CFDictionaryRef stdAttrTypeDict; stdAttrTypeDict = (CFDictionaryRef)CFArrayGetValueAtIndex( inAttrTypeMapCFArray, commonIndex-1 ); if ( stdAttrTypeDict != nil ) { if ( CFDictionaryContainsKey( stdAttrTypeDict, CFSTR( kXMLStdNameKey ) ) ) { CFStringRef attrMapString; attrMapString = (CFStringRef)CFDictionaryGetValue( stdAttrTypeDict, CFSTR( kXMLStdNameKey ) ); if ( attrMapString != nil ) { bool bNoDuplicate = true; //this is the Std Attr Name that we compare to if //cfAttrMapCount is not zero ie. there were record specific attr maps that //we do not wish to add to here if ( (cfAttrMapArrayRef != NULL) && (cfAttrMapCount != 0) ) { for (sInt32 aIndex = 0; aIndex < cfAttrMapCount; aIndex++) { //determine whether the array entry is a dict if (CFGetTypeID(CFArrayGetValueAtIndex( cfAttrMapArrayRef, aIndex )) == CFDictionaryGetTypeID()) { CFDictionaryRef stdAttrTypeDict; stdAttrTypeDict = (CFDictionaryRef)CFArrayGetValueAtIndex( cfAttrMapArrayRef, aIndex ); if ( stdAttrTypeDict != nil ) { if ( CFDictionaryContainsKey( stdAttrTypeDict, CFSTR( kXMLStdNameKey ) ) ) { CFStringRef attrMapStringOld; attrMapStringOld = (CFStringRef)CFDictionaryGetValue( stdAttrTypeDict, CFSTR( kXMLStdNameKey ) ); if ( attrMapStringOld != nil ) { if (CFStringCompare(attrMapStringOld, attrMapString, 0) == kCFCompareEqualTo) { bNoDuplicate = false; bUsedIndex = false; inIndex++; break; } //CFRelease(attrMapStringOld); // no since pointer only from Get }// if ( attrMapStringOld != nil ) } //std attr name present } //std attr type dict present } }//for (uInt32 aIndex = 0; aIndex < cfAttrMapCount; aIndex++) } if (bNoDuplicate) { if (CFStringGetCString(attrMapString, tmpBuff, cfBuffSize, kCFStringEncodingUTF8)) { outResult = (char *) calloc(1, 1+strlen(tmpBuff)); ::strcpy(outResult, tmpBuff); } } //CFRelease(attrMapString); // no since pointer only from Get }// if ( attrMapString != nil ) } //std attr name present } //std attr type dict present } free(tmpBuff); }//get the correct indexed Native Map }// (cfAttrMapCount2 != 0) }// if (inAttrTypeMapCFArray != nil) } //(!bUsedIndex) //done so don't look for any more break; } } //CFRelease(cfStringRef); // no since pointer only from Get } } //CFRelease( typeMapDict ); // no since pointer only from Get }//if ( typeMapDict != nil ) } // loop over std rec maps - break above takes us out of this loop } // if (cfMapCount != 0) CFRelease(cfRecTypeRef); } // if (inRecordTypeMapCFArray != nil) ie. an array of Record Maps exists if (inIndex != inputIndex) { inputIndex = inIndex; } return( outResult ); } // ExtractStdAttr // --------------------------------------------------------------------------- // * AttrMapsCount // --------------------------------------------------------------------------- int CLDAPv3Configs::AttrMapsCount( char *inRecType, char *inAttrType, CFArrayRef inRecordTypeMapCFArray, CFArrayRef inAttrTypeMapCFArray ) { int outCount = 0; CFIndex cfMapCount = 0; sInt32 iMapIndex = 0; CFStringRef cfStringRef = nil; CFStringRef cfRecTypeRef = nil; CFStringRef cfAttrTypeRef = nil; CFArrayRef cfAttrMapArrayRef = nil; bool bNoRecSpecificAttrMap = true; if ( (inRecordTypeMapCFArray != nil) && (inRecType != nil) && (inAttrType != nil) ) { cfRecTypeRef = CFStringCreateWithCString(kCFAllocatorDefault, inRecType, kCFStringEncodingUTF8); cfAttrTypeRef = CFStringCreateWithCString(kCFAllocatorDefault, inAttrType, kCFStringEncodingUTF8); //now we can look for our Type mapping cfMapCount = ::CFArrayGetCount( inRecordTypeMapCFArray ); if (cfMapCount != 0) { //loop through the maps for (iMapIndex = 0; iMapIndex < cfMapCount; iMapIndex++) { CFDictionaryRef typeMapDict; typeMapDict = (CFDictionaryRef)::CFArrayGetValueAtIndex( inRecordTypeMapCFArray, iMapIndex ); if ( typeMapDict != nil ) { //retrieve the mappings // get the standard type label first if ( CFDictionaryContainsKey( typeMapDict, CFSTR( kXMLStdNameKey ) ) ) { cfStringRef = (CFStringRef)CFDictionaryGetValue( typeMapDict, CFSTR( kXMLStdNameKey ) ); if ( cfStringRef != nil ) { if ( CFGetTypeID( cfStringRef ) == CFStringGetTypeID() ) { if (CFStringCompare(cfStringRef, cfRecTypeRef, 0) == kCFCompareEqualTo) { // found the std mapping // get the Attr map array for this std rec map cfAttrMapArrayRef = GetAttributeTypeMapArray(typeMapDict); outCount = AttrMapFromArrayCount( cfAttrTypeRef, cfAttrMapArrayRef, &bNoRecSpecificAttrMap ); if (bNoRecSpecificAttrMap) { //here we search the COMMON attr maps if std attr type not found above outCount = AttrMapFromArrayCount( cfAttrTypeRef, inAttrTypeMapCFArray, &bNoRecSpecificAttrMap ); //here don't care about the return of bNoRecSpecificAttrMap } //done so don't look for any more break; } } //CFRelease(cfStringRef); // no since pointer only from Get } } //CFRelease( typeMapDict ); // no since pointer only from Get }//if ( typeMapDict != nil ) } // loop over std rec maps - break above takes us out of this loop } // if (cfMapCount != 0) CFRelease(cfRecTypeRef); CFRelease(cfAttrTypeRef); } // if (inRecordTypeMapCFArray != nil) ie. an array of Record Maps exists return( outCount ); } // AttrMapsCount // --------------------------------------------------------------------------- // * AttrMapFromArrayCount // --------------------------------------------------------------------------- int CLDAPv3Configs::AttrMapFromArrayCount( CFStringRef inAttrTypeRef, CFArrayRef inAttrTypeMapCFArray, bool *bNoRecSpecificAttrMap ) { int outCount = 0; CFIndex cfAttrMapCount = 0; sInt32 iAttrMapIndex = 0; CFStringRef cfAttrStringRef = nil; CFArrayRef cfNativeMapArrayRef = nil; if ( (inAttrTypeRef != nil) && (inAttrTypeMapCFArray != nil) ) { //now we search for the inAttrType cfAttrMapCount = ::CFArrayGetCount( inAttrTypeMapCFArray ); //check here that we have a potential entry //ie. std type not nil and an entry in the native map array if (cfAttrMapCount != 0) { //loop through the Attr maps for (iAttrMapIndex = 0; iAttrMapIndex < cfAttrMapCount; iAttrMapIndex++) { CFDictionaryRef typeAttrMapDict; typeAttrMapDict = (CFDictionaryRef)::CFArrayGetValueAtIndex( inAttrTypeMapCFArray, iAttrMapIndex ); if ( typeAttrMapDict != nil ) { //retrieve the mappings // get the standard Attr type label first if ( CFDictionaryContainsKey( typeAttrMapDict, CFSTR( kXMLStdNameKey ) ) ) { cfAttrStringRef = (CFStringRef)CFDictionaryGetValue( typeAttrMapDict, CFSTR( kXMLStdNameKey ) ); if ( cfAttrStringRef != nil ) { if ( CFGetTypeID( cfAttrStringRef ) == CFStringGetTypeID() ) { if (CFStringCompare(cfAttrStringRef, inAttrTypeRef, 0) == kCFCompareEqualTo) { *bNoRecSpecificAttrMap = false; //found a rec type map specific attr map // found the std Attr mapping // get the native map array for this std Attr map cfNativeMapArrayRef = GetNativeTypeMapArray(typeAttrMapDict); if (cfNativeMapArrayRef != nil) { //now we search for the inAttrType outCount = ::CFArrayGetCount( cfNativeMapArrayRef ); }// if (cfNativeMapArrayRef != nil) //done so don't look for any more break; } } //CFRelease(cfAttrStringRef); // no since pointer only from Get } } //CFRelease( typeAttrMapDict ); // no since pointer only from Get }//if ( typeAttrMapDict != nil ) } //loop over the Attr maps }// if (cfAttrMapCount != 0) }// if (inAttrTypeMapCFArray != nil) return(outCount); } // AttrMapFromArrayCount void CLDAPv3Configs::XMLConfigLock( void ) { if (pXMLConfigLock != nil) { pXMLConfigLock->Wait(); } } void CLDAPv3Configs::XMLConfigUnlock( void ) { if (pXMLConfigLock != nil) { pXMLConfigLock->Signal(); } }