#ifndef __CLDAPNode_h__
#define __CLDAPNode_h__ 1
#include <stdio.h>
#include <string.h> //used for strcpy, etc.
#include <stdlib.h> //used for malloc
#include <map> //STL map class
#include <string> //STL string class
#include <vector> //STL vector class
#include <time.h> //time_t usage
#include "DirServices.h"
#include "DirServicesUtils.h"
#include "DirServicesConst.h"
#include "PrivateTypes.h"
#include "DSCThread.h"
#include "DSMutexSemaphore.h"
#include "CLDAPv3Configs.h"
#include <lber.h>
#include <ldap.h>
using namespace std;
#define kMinTimeToLogLockBeingHeld 1
struct sLDAPNodeStruct
{
char *fNodeName; char *fLDAPServer;
LDAP *fHost; DSMutexSemaphore
*fLDAPSessionMutex;
uInt32 fRefCount; uInt32 fConnectionActiveCount;
char *fDirectServerName; int fDirectLDAPPort;
bool bAuthCallActive; bool bBadSession;
char *fKerberosId; char *fLDAPUserName; void *fLDAPCredentials; uInt32 fLDAPCredentialsLen; char *fLDAPAuthType;
int fConnectionStatus; time_t fDelayedBindTime;
int fIdleTOCount; int fIdleTO; int fDelayRebindTry;
double fLDAPSessionMutexStartTime;
public:
sLDAPNodeStruct( void );
~sLDAPNodeStruct( void );
sLDAPNodeStruct( const sLDAPNodeStruct &inLDAPNodeStruct);
#define SessionMutexWait() SessionMutexWaitWithFunctionName(__PRETTY_FUNCTION__)
#define SessionMutexSignal() SessionMutexSignalWithFunctionName(__PRETTY_FUNCTION__)
void SessionMutexWaitWithFunctionName ( const char* callingFunction );
void SessionMutexSignalWithFunctionName ( const char* callingFunction );
void setLastLDAPServer( const char *inServer )
{
SessionMutexWait();
if( fLDAPServer )
{
delete fLDAPServer;
}
fLDAPServer = (inServer ? strdup(inServer) : NULL);
SessionMutexSignal();
}
void updateCredentials( void *inLDAPCredentials, uInt32 inLDAPCredentialLen, char *inAuthType );
inline void ChangeRefCountBy( int inValue )
{
SessionMutexWait();
fRefCount += inValue;
if ( bAuthCallActive && fRefCount <= 0 && fHost != NULL )
{
ldap_unbind(fHost);
fHost = NULL;
}
SessionMutexSignal();
}
};
struct sLDAPContextData
{
char *fNodeName; int fType; uInt32 offset; uInt32 index;
char *fOpenRecordType; char *fOpenRecordName; char *fOpenRecordDN;
bool bLDAPv2ReadOnly;
char *fAuthUserName; void *fAuthCredential; uInt32 fAuthCredentialLen; char *fAuthType;
tDirReference fPWSRef;
tDirNodeReference fPWSNodeRef;
unsigned long fPWSUserIDLength;
char *fPWSUserID;
uid_t fUID;
uid_t fEffectiveUID;
sLDAPNodeStruct *fLDAPNodeStruct;
public:
sLDAPContextData( void );
~sLDAPContextData( void );
sLDAPContextData( const sLDAPContextData& inContextData );
void setCredentials( char *inUserName, void *inCredential, uInt32 inCredentialLen, char *inAuthType );
};
typedef map<string, sLDAPNodeStruct*> LDAPNodeMap;
typedef LDAPNodeMap::iterator LDAPNodeMapI;
typedef vector<sLDAPNodeStruct*> LDAPNodeVector;
typedef LDAPNodeVector::iterator LDAPNodeVectorI;
enum {
kConnectionSafe = 0,
kConnectionUnsafe,
kConnectionUnknown
};
class CLDAPNode
{
public:
static bool fCheckThreadActive;
public:
CLDAPNode ( void );
virtual ~CLDAPNode ( void );
#define NodeOpenMutexWaitButNotForCheckFailedThread() \
NodeOpenMutexWaitWithFunctionName(__PRETTY_FUNCTION__, false)
#define NodeOpenMutexWait() \
NodeOpenMutexWaitWithFunctionName(__PRETTY_FUNCTION__, true)
void NodeOpenMutexWaitWithFunctionName ( const char* callingFunction, bool waitForCheckFailedThreadToComplete );
#define NodeOpenMutexSignal() \
NodeOpenMutexSignalWithFunctionName(__PRETTY_FUNCTION__)
void NodeOpenMutexSignalWithFunctionName ( const char* callingFunction );
sInt32 SafeOpen ( char *inNodeName,
sLDAPNodeStruct **inLDAPNodeStruct );
sInt32 AuthOpen ( char *inLDAPUserName,
char *inKerberosId,
void *inLDAPCredentials,
uInt32 inLDAPCredentialsLen,
char *inLDAPAuthType,
sLDAPNodeStruct **outLDAPNodeStruct );
sInt32 RebindSession ( sLDAPNodeStruct *pLDAPNodeStruct );
sInt32 SimpleAuth ( sLDAPNodeStruct *inLDAPNodeStruct,
char *inLDAPUserName,
void *inLDAPCredentials,
uInt32 inLDAPCredentialsLen,
char *inKerberosId );
void GetSchema ( sLDAPContextData *inContext );
void SessionMapMutexLock
( void ) {fLDAPNodeOpenMutex.Wait();}
void SessionMapMutexUnlock
( void ) {fLDAPNodeOpenMutex.Signal();}
LDAP* LockSession ( sLDAPContextData *inContext );
void UnLockSession ( sLDAPContextData *inContext, bool inHasFailed = false );
void CheckIdles ( void );
void CheckFailed ( void );
void EnsureCheckFailedConnectionsThreadIsRunning ( void );
void SystemGoingToSleep ( void );
void SystemWillPowerOn ( void );
void NetTransition ( void );
LDAP* InitLDAPConnection
( sLDAPNodeStruct *inLDAPNodeStruct,
sLDAPConfigData *inConfig,
bool bInNeedWriteable = false );
static struct addrinfo*
ResolveHostName ( CFStringRef inServerNameRef,
int inPortNumber );
static LDAP* EstablishConnection
( sLDAPNodeStruct *inLDAPNodeStruct,
sReplicaInfo *inList,
int inPort,
int inOpenTimeout,
bool bInNeedWriteable = false );
bool isSASLMethodSupported ( CFStringRef inMethod );
void ForcedSafeClose ( const char *inNodeName );
void CredentialChange( sLDAPNodeStruct *inLDAPNodeStruct, char *inUserDN );
void RereadDefinedReplicas ( sLDAPNodeStruct *inLDAPNodeStruct );
protected:
sInt32 BindProc ( sLDAPNodeStruct *inLDAPNodeStruct,
bool bForceBind = false,
bool bCheckPasswordOnly = false,
bool bNeedWriteable = false );
sInt32 ParseLDAPNodeName ( char *inNodeName,
char **outLDAPName,
int *outLDAPPort );
sInt32 GetSchemaMessage ( LDAP *inHost,
int inSearchTO,
LDAPMessage **outResultMsg );
char** GetNamingContexts ( LDAP *inHost,
int inSearchTO,
uInt32 *outCount );
void MergeArraysRemovingDuplicates
( CFMutableArrayRef cfPrimaryArray,
CFArrayRef cfArrayToAdd );
void BuildReplicaInfoLinkList
( sReplicaInfo **inOutList,
CFArrayRef inRepList,
CFArrayRef inWriteableList,
int inPort );
sInt32 GetReplicaListFromConfigRecord
( LDAP *inHost,
int inSearchTO,
sLDAPNodeStruct *inLDAPNodeStruct,
CFMutableArrayRef inOutRepList,
CFMutableArrayRef inOutWriteableList );
sInt32 GetReplicaListFromAltServer
( LDAP *inHost,
int inSearchTO,
CFMutableArrayRef inOutRepList );
sInt32 GetReplicaListFromDNS
( sLDAPNodeStruct *inLDAPNodeStruct,
CFMutableArrayRef inOutRepList );
sInt32 RetrieveDefinedReplicas
( sLDAPNodeStruct *inLDAPNodeStruct,
CFMutableArrayRef &inOutRepList,
CFMutableArrayRef &inOutWriteableList,
int inPort,
sReplicaInfo **inOutList );
bool IsTokenNotATag ( char *inToken );
void RetrieveServerMappingsIfRequired
( sLDAPNodeStruct *inLDAPNodeStruct );
static char * LDAPWithBlockingSocket
( struct addrinfo *addrInfo, int seconds );
static char * ConvertToIPAddress ( struct addrinfo *addrInfo );
static bool IsLocalAddress ( struct addrinfo *addrInfo );
static bool ReachableAddress ( struct addrinfo *addrInfo );
void CheckSASLMethods ( sLDAPNodeStruct *inLDAPNodeStruct );
bool LocalServerIsLDAPReplica ( void );
private:
CFMutableArrayRef fSupportedSASLMethods;
LDAPNodeMap fLDAPNodeMap;
DSMutexSemaphore fLDAPNodeOpenMutex; bool fInStartupState;
};
#endif // __CLDAPNode_h__