📄 pgpldap.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: pgpLDAP.c,v 1.42 2002/08/06 20:11:12 dallen Exp $
____________________________________________________________________________*/
#include <string.h>
#include "pgpLDAPPriv.h"
#include "pgpBERPriv.h"
#include "pgpPFLPriv.h"
#include "pgpErrors.h"
#include "pgpMem.h"
#include "pgpSockets.h"
#include "pgpUtilities.h"
#include "pgpContext.h"
#include "pgpStrings.h"
typedef struct PGPldapResultEntry
{
PGPldapResult result;
PGPError err;
} PGPldapResultEntry;
#define EN(number, err) { number, err }
static const PGPldapResultEntry sResults[] =
{
EN( kPGPldapResult_Success, kPGPError_NoErr ),
EN( kPGPldapResult_OperationsError, kPGPError_LDAPOperationsError ),
EN( kPGPldapResult_ProtocolError, kPGPError_LDAPProtocolError ),
EN( kPGPldapResult_TimelimitExceeded, kPGPError_LDAPTimelimitExceeded ),
EN( kPGPldapResult_SizelimitExceeded, kPGPError_LDAPSizelimitExceeded ),
EN( kPGPldapResult_CompareFalse, kPGPError_NoErr ),
EN( kPGPldapResult_CompareTrue, kPGPError_NoErr ),
EN( kPGPldapResult_StrongAuthNotSupported, kPGPError_LDAPStrongAuthNotSupported ),
EN( kPGPldapResult_StrongAuthRequired, kPGPError_LDAPStrongAuthRequired ),
EN( kPGPldapResult_PartialResults, kPGPError_LDAPPartialResults ),
EN( kPGPldapResult_NoSuchAttribute, kPGPError_LDAPNoSuchAttribute ),
EN( kPGPldapResult_UndefinedType, kPGPError_LDAPUndefinedType ),
EN( kPGPldapResult_InappropriateMatching, kPGPError_LDAPInappropriateMatching ),
EN( kPGPldapResult_ConstraintViolation, kPGPError_LDAPConstraintViolation ),
EN( kPGPldapResult_TypeOrValueExists, kPGPError_LDAPTypeOrValueExists ),
EN( kPGPldapResult_InvalidSyntax, kPGPError_LDAPInvalidSyntax ),
EN( kPGPldapResult_NoSuchObject, kPGPError_LDAPNoSuchObject ),
EN( kPGPldapResult_AliasProblem, kPGPError_LDAPAliasProblem ),
EN( kPGPldapResult_InvalidDNSyntax, kPGPError_LDAPInvalidDNSyntax ),
EN( kPGPldapResult_IsLeaf, kPGPError_LDAPIsLeaf ),
EN( kPGPldapResult_AliasDerefProblem, kPGPError_LDAPAliasDerefProblem ),
EN( kPGPldapResult_InappropriateAuth, kPGPError_LDAPInappropriateAuth ),
EN( kPGPldapResult_InvalidCredentials, kPGPError_LDAPInvalidCredentials ),
EN( kPGPldapResult_InsufficientAccess, kPGPError_LDAPInsufficientAccess ),
EN( kPGPldapResult_Busy, kPGPError_LDAPBusy ),
EN( kPGPldapResult_Unavailable, kPGPError_LDAPUnavailable ),
EN( kPGPldapResult_UnwillingToPerform, kPGPError_LDAPUnwillingToPerform ),
EN( kPGPldapResult_LoopDetect, kPGPError_LDAPLoopDetect ),
EN( kPGPldapResult_NamingViolation, kPGPError_LDAPNamingViolation ),
EN( kPGPldapResult_ObjectClassViolation, kPGPError_LDAPObjectClassViolation ),
EN( kPGPldapResult_NotAllowedOnNonleaf, kPGPError_LDAPNotAllowedOnNonleaf ),
EN( kPGPldapResult_NotAllowedOnRDN, kPGPError_LDAPNotAllowedOnRDN ),
EN( kPGPldapResult_AlreadyExists, kPGPError_LDAPAlreadyExists ),
EN( kPGPldapResult_NoObjectClassMods, kPGPError_LDAPNoObjectClassMods ),
EN( kPGPldapResult_ResultsTooLarge, kPGPError_LDAPResultsTooLarge ),
EN( kPGPldapResult_Other, kPGPError_LDAPOther ),
EN( kPGPldapResult_ServerDown, kPGPError_LDAPServerDown ),
EN( kPGPldapResult_LocalError, kPGPError_LDAPLocalError ),
EN( kPGPldapResult_EncodingError, kPGPError_LDAPEncodingError ),
EN( kPGPldapResult_DecodingError, kPGPError_LDAPDecodingError ),
EN( kPGPldapResult_Timeout, kPGPError_LDAPTimeout ),
EN( kPGPldapResult_AuthUnknown, kPGPError_LDAPAuthUnknown ),
EN( kPGPldapResult_FilterError, kPGPError_LDAPFilterError ),
EN( kPGPldapResult_UserCancelled, kPGPError_LDAPUserCancelled ),
EN( kPGPldapResult_ParamError, kPGPError_LDAPParamError ),
EN( kPGPldapResult_NoMemory, kPGPError_OutOfMemory ),
EN( kPGPldapResult_ConnectError, kPGPError_LDAPConnectError )
};
#define kPGPldapResult_NumResultTableEntries \
( sizeof( sResults ) / sizeof( sResults[ 0 ] ) )
#undef EN
PGPError
PGPNewLDAPContext(
PGPContextRef context,
PGPldapContextRef * pgpLDAP )
{
PGPError err = kPGPError_NoErr;
PGPMemoryMgrRef memMgr = kInvalidPGPMemoryMgrRef;
PGPValidatePtr( pgpLDAP );
PGPValidateContext( context );
memMgr = PGPPeekContextMemoryMgr( context );
/* Allocate the PGPldap struct */
*pgpLDAP = PGPNewData( memMgr,
sizeof( PGPldapContext ),
kPGPMemoryMgrFlags_Clear );
if( IsNull( pgpLDAP ) )
return kPGPError_OutOfMemory;
(*pgpLDAP)->hostname = NULL;
(*pgpLDAP)->port = 0;
(*pgpLDAP)->sock = kInvalidPGPSocketRef;
(*pgpLDAP)->nextMessageID = 0;
(*pgpLDAP)->response = NULL;
(*pgpLDAP)->sizelimit = 0;
(*pgpLDAP)->timelimit = 0;
(*pgpLDAP)->deref = kPGPldapDeref_Never;
(*pgpLDAP)->result = kPGPldapResult_Success;
(*pgpLDAP)->matched = NULL;
(*pgpLDAP)->message = NULL;
(*pgpLDAP)->threadFns.pgpLDAPThread_MutexAlloc = NULL;
(*pgpLDAP)->threadFns.pgpLDAPThread_MutexFree = NULL;
(*pgpLDAP)->threadFns.pgpLDAPThread_MutexLock = NULL;
(*pgpLDAP)->threadFns.pgpLDAPThread_MutexUnlock = NULL;
(*pgpLDAP)->threadFns.pgpLDAPThread_SetErrno = NULL;
(*pgpLDAP)->threadFns.pgpLDAPThread_GetErrno = NULL;
(*pgpLDAP)->threadFns.pgpLDAPThread_SetLDAPErrno = NULL;
(*pgpLDAP)->threadFns.pgpLDAPThread_GetLDAPErrno = NULL;
(*pgpLDAP)->memMgr = memMgr;
return err;
}
PGPError
PGPNewLDAPMessage(
PGPldapContextRef pgpLDAP,
PGPldapMessageRef * message )
{
PGPError err = kPGPError_NoErr;
PGPValidateLDAPContextRef( pgpLDAP );
PGPValidatePtr( message );
*message = PGPNewData( pgpLDAP->memMgr,
sizeof( PGPldapMessage ),
kPGPMemoryMgrFlags_Clear );
if( IsNull( message ) )
return kPGPError_OutOfMemory;
(*message)->messageID = 0;
(*message)->type = kPGPldapType_None;
(*message)->prev = NULL;
(*message)->next = NULL;
return err;
}
static PGPError
pgpFreeLDAPMessageRef(
PGPldapMessageRef message,
PGPBoolean freeBER )
{
PGPValidateLDAPMessageRef( message );
/* Reset the pointers */
if( message->next )
(void) pgpFreeLDAPMessageRef( message->next, freeBER );
if( message->prev )
message->prev->next = NULL;
if( freeBER )
(void) PGPFreeBERElement( message->ber );
(void) PGPFreeData( message );
return kPGPError_NoErr;
}
PGPError
PGPFreeLDAPContext(
PGPldapContextRef pgpLDAP )
{
PGPValidateLDAPContextRef( pgpLDAP );
if( PGPldapMessageRefIsValid( pgpLDAP->response ) )
(void) pgpFreeLDAPMessageRef( pgpLDAP->response, TRUE );
if( PGPSocketRefIsValid( pgpLDAP->sock ) )
(void) PGPCloseSocket( pgpLDAP->sock );
if( IsntNull (pgpLDAP->hostname ) )
(void) PGPFreeData( pgpLDAP->hostname );
if( IsntNull (pgpLDAP->matched ) )
(void) PGPFreeData( pgpLDAP->matched );
if( IsntNull (pgpLDAP->message ) )
(void) PGPFreeData( pgpLDAP->message );
(void) PGPFreeData( pgpLDAP );
return kPGPError_NoErr;
}
/*
* This frees not just the single PGPldapMessage, but all the
* PGPldapMessages in the 'next' chain of PGPldapMessages.
*
* Note: even though each PGPldapMessage has a pointer to a PGPberElement,
* as far as memory allocation is concerned, the PGPberElements actually
* belong to the PGPldapContext and are freed when we call
* PGPFreeLDAPContext, not PGPFreeLDAPMessage.
*/
PGPError
PGPFreeLDAPMessage(
PGPldapMessageRef message )
{
PGPValidateLDAPMessageRef( message );
(void) pgpFreeLDAPMessageRef( message, FALSE );
return kPGPError_NoErr;
}
PGPError
PGPFreeLDAPValues(
char ** vals )
{
PGPUInt32 i = 0;
PGPValidatePtr( vals );
for( i = 0; vals[i] != NULL; i++ )
(void) PGPFreeData( vals[i] );
(void) PGPFreeData( vals );
return kPGPError_NoErr;
}
PGPError
PGPFreeLDAPValuesLen(
PGPberValue ** bvals )
{
PGPUInt32 i = 0;
PGPValidatePtr( bvals );
for( i = 0; bvals[i] != NULL; i++ )
{
(void) PGPFreeData( bvals[i]->value );
(void) PGPFreeData( bvals[i] );
}
(void) PGPFreeData( bvals );
return kPGPError_NoErr;
}
PGPError
pgpNewLDAPURLDesc(
PGPldapContextRef pgpLDAP,
PGPldapURLDesc ** lud )
{
PGPError err = kPGPError_NoErr;
PGPValidatePtr( lud );
*lud = PGPNewData( pgpLDAP->memMgr, sizeof( PGPldapURLDesc ),
kPGPMemoryMgrFlags_Clear );
CKNULL( *lud );
(*lud)->host = NULL;
(*lud)->port = 0;
(*lud)->dn = NULL;
(*lud)->attrs = NULL;
(*lud)->scope = kPGPldapScope_Base;
(*lud)->filter = PGPNewData( pgpLDAP->memMgr,
strlen( kPGPldap_DefaultFilterString ) + 1,
kPGPMemoryMgrFlags_Clear );
CKNULL( (*lud)->filter );
pgpCopyMemory( kPGPldap_DefaultFilterString, (*lud)->filter,
strlen( kPGPldap_DefaultFilterString ) + 1 );
goto done;
error:
if( IsntNull( *lud ) )
{
if( IsntNull( (*lud)->filter ) )
(void) PGPFreeData( (*lud)->filter );
(void) PGPFreeData( *lud );
}
done:
return err;
}
PGPError
PGPFreeLDAPURLDesc(
PGPldapURLDesc * lud )
{
PGPUInt32 i = 0;
PGPValidatePtr( lud );
if( IsntNull( lud->host ) )
(void) PGPFreeData( lud->host );
if( IsntNull( lud->dn ) )
(void) PGPFreeData( lud->dn );
if( IsntNull( lud->attrs ) )
{
for( i = 0; lud->attrs[i] != NULL; i++ )
(void) PGPFreeData( lud->attrs[i] );
(void) PGPFreeData( lud->attrs );
}
if( IsntNull( lud->filter ) )
(void) PGPFreeData( lud->filter );
(void) PGPFreeData( lud );
return kPGPError_NoErr;
}
PGPError
PGPldapGetErrno(
PGPldapContextRef pgpLDAP,
char ** matched,
char ** message,
PGPldapResult * result )
{
PGPValidateLDAPContextRef( pgpLDAP );
PGPValidatePtr( result );
*result = pgpLDAP->result;
if( IsntNull( matched ) && ( matched[0] != '\0' ) )
*matched = pgpLDAP->matched;
if( IsntNull( message ) && ( message[0] != '\0' ) )
*message = pgpLDAP->message;
return kPGPError_NoErr;
}
PGPError
PGPldapResultToError(
PGPldapContextRef pgpLDAP,
PGPldapResult result )
{
PGPError err = kPGPError_NoErr;
PGPUInt32 i = 0;
const PGPldapResultEntry * entry = NULL;
(void) pgpLDAP;
for( i = 0; i < kPGPldapResult_NumResultTableEntries; i++ )
{
entry = &sResults[i];
if( entry->result == result )
{
err = entry->err;
break;
}
}
if( i == kPGPldapResult_NumResultTableEntries )
err = kPGPError_LDAPOther;
return err;
}
static PGPError
pgpLDAPConnect(
PGPldapContextRef pgpLDAP,
char * host,
PGPUInt16 port )
{
PGPSocketAddressInternet sin;
PGPHostEntry *hp = NULL;
PGPInt32 i = 0;
PGPUInt32 ipAddress = 0;
PGPBoolean bConnected = FALSE;
PGPError err = kPGPError_NoErr;
PGPValidateLDAPContextRef( pgpLDAP );
PGPValidatePtr( host );
err = PGPSocketsInit();
if( IsPGPError( err ) )
{
err = PGPGetLastSocketsError();
goto error;
}
pgpLDAP->sock = PGPOpenSocket(
kPGPAddressFamilyInternet,
kPGPSocketTypeStream,
kPGPTCPProtocol );
if( pgpLDAP->sock == kInvalidPGPSocketRef )
{
err = PGPGetLastSocketsError();
goto error;
}
ipAddress = PGPDottedToInternetAddress( host );
if( ipAddress != 0xFFFFFFFF )
{
(void) memset( &sin, 0, sizeof ( sin ) );
sin.sin_family = kPGPAddressFamilyInternet;
sin.sin_port = PGPHostToNetShort( port );
(void) memcpy( &sin.sin_addr.s_addr, (void *) &ipAddress,
sizeof( sin.sin_addr.s_addr ) );
if( PGPConnect( pgpLDAP->sock,
(PGPSocketAddress *) &sin,
sizeof( sin ) ) >= 0 )
{
bConnected = TRUE;
}
else if( PGPGetLastSocketsError() == kPGPError_UserAbort )
{
err = kPGPError_UserAbort;
goto error;
}
}
if( !bConnected )
{
/* Connecting to the IP address didn't work */
hp = PGPGetHostByName( host );
if( IsNull ( hp ) )
return PGPGetLastSocketsError();
(void) memset( &sin, 0, sizeof ( sin ) );
sin.sin_family = kPGPAddressFamilyInternet;
sin.sin_port = PGPHostToNetShort( port );
for( i = 0; hp->h_addr_list[i] != NULL; i++ )
{
(void) memcpy( &sin.sin_addr.s_addr, hp->h_addr_list[i],
sizeof( sin.sin_addr.s_addr ) );
if( PGPConnect( pgpLDAP->sock,
(PGPSocketAddress *) &sin,
sizeof( sin ) ) >= 0 )
{
bConnected = TRUE;
}
else if( PGPGetLastSocketsError() == kPGPError_UserAbort )
{
err = kPGPError_UserAbort;
goto error;
}
}
}
if( bConnected )
{
/* Connected */
pgpLDAP->hostname = PGPNewData( pgpLDAP->memMgr,
strlen( host ) + 1,
kPGPMemoryMgrFlags_Clear );
if( IsNull( pgpLDAP->hostname ) )
{
err = kPGPError_OutOfMemory;
goto error;
}
pgpCopyMemory( host, pgpLDAP->hostname, strlen( (char *)host ) + 1 );
pgpLDAP->port = port;
}
else
{
if( !PGPSocketRefIsValid( pgpLDAP->sock ) )
PGPCloseSocket( pgpLDAP->sock );
/* Didn't connect */
err = kPGPError_SocketsNotConnected;
}
goto done;
error:
done:
return err;
}
PGPError
pgpLDAPSend(
PGPldapContextRef pgpLDAP,
PGPberElementRef ber )
{
PGPUInt32 bytesSent = 0;
PGPByte * encoding = NULL;
PGPSize length = 0;
PGPError err = kPGPError_NoErr;
PGPValidateLDAPContextRef( pgpLDAP );
PGPValidateBERElementRef( ber );
if( pgpLDAP->sock == kInvalidPGPSocketRef )
{
err = kPGPError_SocketsNotConnected;
goto error;
}
err = PGPberGetLength( ber, &length ); CKERR;
err = PGPberGetEncoding( ber, &encoding ); CKERR;
bytesSent = PGPSend( pgpLDAP->sock, encoding, length,
kPGPSendFlagNone );
if( bytesSent != length )
err = PGPGetLastSocketsError();
error:
return err;
}
PGPError
PGPldapOpen(
PGPldapContextRef pgpLDAP,
char * host,
PGPUInt16 port )
{
PGPError err = kPGPError_NoErr;
char * singleHost = NULL;
PGPBoolean connected = FALSE;
PGPUInt32 i = 0;
PGPUInt32 j = 0;
PGPValidateLDAPContextRef( pgpLDAP );
PGPValidatePtr( host );
singleHost = PGPNewData( pgpLDAP->memMgr, strlen( host ) + 1,
kPGPMemoryMgrFlags_Clear );
CKNULL( singleHost );
while( !connected )
{
while( host[i] == ' ' )
i++;
if( host[i] == '\0' )
{
pgpLDAP->result = kPGPldapResult_ConnectError;
if( IsntPGPError( err ) )
err = PGPldapResultToError( pgpLDAP, pgpLDAP->result );
goto error;
}
j = 0;
while( ( host[i] != ' ' ) && ( host[i] != '\0' ) )
{
singleHost[j++] = host[i++];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -