⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpldap.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 5 页
字号:
/*____________________________________________________________________________
	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 + -