openldap/servers/slapd/slapi/slapi_pblock.c

555 lines
13 KiB
C
Raw Normal View History

2003-11-30 02:03:43 +08:00
/* $OpenLDAP$ */
2003-11-27 00:05:06 +08:00
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
2004-01-02 03:15:16 +08:00
* Copyright 2002-2004 The OpenLDAP Foundation.
2003-11-27 00:05:06 +08:00
* Portions Copyright 1997,2002-2003 IBM Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
2003-11-27 00:05:06 +08:00
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENTS:
* This work was initially developed by IBM Corporation for use in
* IBM products and subsequently ported to OpenLDAP Software by
* Steve Omrani. Additional significant contributors include:
* Luke Howard
*/
#include "portable.h"
#include <slap.h>
#include <slapi.h>
static int
isOkNetscapeParam( int param )
{
switch ( param ) {
case SLAPI_BACKEND:
case SLAPI_CONNECTION:
case SLAPI_OPERATION:
case SLAPI_OPERATION_PARAMETERS:
case SLAPI_OPERATION_TYPE:
case SLAPI_OPERATION_ID:
case SLAPI_OPERATION_AUTHTYPE:
case SLAPI_REQUESTOR_ISROOT:
case SLAPI_BE_MONITORDN:
case SLAPI_BE_TYPE:
case SLAPI_BE_READONLY:
case SLAPI_BE_LASTMOD:
case SLAPI_CONN_ID:
case SLAPI_OPINITIATED_TIME:
case SLAPI_REQUESTOR_DN:
case SLAPI_REQUESTOR_ISUPDATEDN:
case SLAPI_CONN_DN:
case SLAPI_CONN_CLIENTIP:
case SLAPI_CONN_SERVERIP:
case SLAPI_CONN_AUTHTYPE:
case SLAPI_CONN_AUTHMETHOD:
case SLAPI_CONN_CERT:
case SLAPI_X_CONN_IS_UDP:
case SLAPI_X_CONN_CLIENTPATH:
case SLAPI_X_CONN_SERVERPATH:
case SLAPI_X_CONN_SSF:
case SLAPI_X_CONN_SASL_CONTEXT:
case SLAPI_IBM_CONN_DN_ALT:
case SLAPI_IBM_CONN_DN_ORIG:
case SLAPI_IBM_GSSAPI_CONTEXT:
case SLAPI_PLUGIN:
case SLAPI_PLUGIN_PRIVATE:
case SLAPI_PLUGIN_TYPE:
case SLAPI_PLUGIN_ARGV:
case SLAPI_PLUGIN_ARGC:
case SLAPI_PLUGIN_VERSION:
case SLAPI_PLUGIN_OPRETURN:
case SLAPI_PLUGIN_OBJECT:
case SLAPI_PLUGIN_DESTROY_FN:
case SLAPI_PLUGIN_DESCRIPTION:
case SLAPI_PLUGIN_INTOP_RESULT:
case SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES:
case SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS:
case SLAPI_PLUGIN_DB_BIND_FN:
case SLAPI_PLUGIN_DB_UNBIND_FN:
case SLAPI_PLUGIN_DB_SEARCH_FN:
case SLAPI_PLUGIN_DB_COMPARE_FN:
case SLAPI_PLUGIN_DB_MODIFY_FN:
case SLAPI_PLUGIN_DB_MODRDN_FN:
case SLAPI_PLUGIN_DB_ADD_FN:
case SLAPI_PLUGIN_DB_DELETE_FN:
case SLAPI_PLUGIN_DB_ABANDON_FN:
case SLAPI_PLUGIN_DB_CONFIG_FN:
case SLAPI_PLUGIN_CLOSE_FN:
case SLAPI_PLUGIN_DB_FLUSH_FN:
case SLAPI_PLUGIN_START_FN:
case SLAPI_PLUGIN_DB_SEQ_FN:
case SLAPI_PLUGIN_DB_ENTRY_FN:
case SLAPI_PLUGIN_DB_REFERRAL_FN:
case SLAPI_PLUGIN_DB_RESULT_FN:
case SLAPI_PLUGIN_DB_LDIF2DB_FN:
case SLAPI_PLUGIN_DB_DB2LDIF_FN:
case SLAPI_PLUGIN_DB_BEGIN_FN:
case SLAPI_PLUGIN_DB_COMMIT_FN:
case SLAPI_PLUGIN_DB_ABORT_FN:
case SLAPI_PLUGIN_DB_ARCHIVE2DB_FN:
case SLAPI_PLUGIN_DB_DB2ARCHIVE_FN:
case SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN:
case SLAPI_PLUGIN_DB_FREE_RESULT_SET_FN:
case SLAPI_PLUGIN_DB_SIZE_FN:
case SLAPI_PLUGIN_DB_TEST_FN:
case SLAPI_PLUGIN_DB_NO_ACL:
case SLAPI_PLUGIN_EXT_OP_FN:
case SLAPI_PLUGIN_EXT_OP_OIDLIST:
case SLAPI_PLUGIN_PRE_BIND_FN:
case SLAPI_PLUGIN_PRE_UNBIND_FN:
case SLAPI_PLUGIN_PRE_SEARCH_FN:
case SLAPI_PLUGIN_PRE_COMPARE_FN:
case SLAPI_PLUGIN_PRE_MODIFY_FN:
case SLAPI_PLUGIN_PRE_MODRDN_FN:
case SLAPI_PLUGIN_PRE_ADD_FN:
case SLAPI_PLUGIN_PRE_DELETE_FN:
case SLAPI_PLUGIN_PRE_ABANDON_FN:
case SLAPI_PLUGIN_PRE_ENTRY_FN:
case SLAPI_PLUGIN_PRE_REFERRAL_FN:
case SLAPI_PLUGIN_PRE_RESULT_FN:
case SLAPI_PLUGIN_POST_BIND_FN:
case SLAPI_PLUGIN_POST_UNBIND_FN:
case SLAPI_PLUGIN_POST_SEARCH_FN:
case SLAPI_PLUGIN_POST_COMPARE_FN:
case SLAPI_PLUGIN_POST_MODIFY_FN:
case SLAPI_PLUGIN_POST_MODRDN_FN:
case SLAPI_PLUGIN_POST_ADD_FN:
case SLAPI_PLUGIN_POST_DELETE_FN:
case SLAPI_PLUGIN_POST_ABANDON_FN:
case SLAPI_PLUGIN_POST_ENTRY_FN:
case SLAPI_PLUGIN_POST_REFERRAL_FN:
case SLAPI_PLUGIN_POST_RESULT_FN:
case SLAPI_PLUGIN_MR_FILTER_CREATE_FN:
case SLAPI_PLUGIN_MR_INDEXER_CREATE_FN:
case SLAPI_PLUGIN_MR_FILTER_MATCH_FN:
case SLAPI_PLUGIN_MR_FILTER_INDEX_FN:
case SLAPI_PLUGIN_MR_FILTER_RESET_FN:
case SLAPI_PLUGIN_MR_INDEX_FN:
case SLAPI_PLUGIN_MR_OID:
case SLAPI_PLUGIN_MR_TYPE:
case SLAPI_PLUGIN_MR_VALUE:
case SLAPI_PLUGIN_MR_VALUES:
case SLAPI_PLUGIN_MR_KEYS:
case SLAPI_PLUGIN_MR_FILTER_REUSABLE:
case SLAPI_PLUGIN_MR_QUERY_OPERATOR:
case SLAPI_PLUGIN_MR_USAGE:
case SLAPI_OP_LESS:
case SLAPI_OP_LESS_OR_EQUAL:
case SLAPI_PLUGIN_MR_USAGE_INDEX:
case SLAPI_PLUGIN_SYNTAX_FILTER_AVA:
case SLAPI_PLUGIN_SYNTAX_FILTER_SUB:
case SLAPI_PLUGIN_SYNTAX_VALUES2KEYS:
case SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA:
case SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB:
case SLAPI_PLUGIN_SYNTAX_NAMES:
case SLAPI_PLUGIN_SYNTAX_OID:
case SLAPI_PLUGIN_SYNTAX_FLAGS:
case SLAPI_PLUGIN_SYNTAX_COMPARE:
case SLAPI_MANAGEDSAIT:
case SLAPI_CONFIG_FILENAME:
case SLAPI_CONFIG_LINENO:
case SLAPI_CONFIG_ARGC:
case SLAPI_CONFIG_ARGV:
case SLAPI_TARGET_DN:
case SLAPI_REQCONTROLS:
case SLAPI_ENTRY_PRE_OP:
case SLAPI_ENTRY_POST_OP:
case SLAPI_RESCONTROLS:
case SLAPI_ADD_RESCONTROL:
case SLAPI_ADD_ENTRY:
case SLAPI_BIND_METHOD:
case SLAPI_BIND_CREDENTIALS:
case SLAPI_BIND_SASLMECHANISM:
case SLAPI_BIND_RET_SASLCREDS:
case SLAPI_COMPARE_TYPE:
case SLAPI_COMPARE_VALUE:
case SLAPI_MODIFY_MODS:
case SLAPI_MODRDN_NEWRDN:
case SLAPI_MODRDN_DELOLDRDN:
case SLAPI_MODRDN_NEWSUPERIOR:
case SLAPI_SEARCH_SCOPE:
case SLAPI_SEARCH_DEREF:
case SLAPI_SEARCH_SIZELIMIT:
case SLAPI_SEARCH_TIMELIMIT:
case SLAPI_SEARCH_FILTER:
case SLAPI_SEARCH_STRFILTER:
case SLAPI_SEARCH_ATTRS:
case SLAPI_SEARCH_ATTRSONLY:
case SLAPI_ABANDON_MSGID:
case SLAPI_SEQ_TYPE:
case SLAPI_SEQ_ATTRNAME:
case SLAPI_SEQ_VAL:
case SLAPI_EXT_OP_REQ_OID:
case SLAPI_EXT_OP_REQ_VALUE:
case SLAPI_EXT_OP_RET_OID:
case SLAPI_EXT_OP_RET_VALUE:
case SLAPI_MR_FILTER_ENTRY:
case SLAPI_MR_FILTER_TYPE:
case SLAPI_MR_FILTER_VALUE:
case SLAPI_MR_FILTER_OID:
case SLAPI_MR_FILTER_DNATTRS:
case SLAPI_LDIF2DB_FILE:
case SLAPI_LDIF2DB_REMOVEDUPVALS:
case SLAPI_DB2LDIF_PRINTKEY:
case SLAPI_PARENT_TXN:
case SLAPI_TXN:
case SLAPI_SEARCH_RESULT_SET:
case SLAPI_SEARCH_RESULT_ENTRY:
case SLAPI_NENTRIES:
case SLAPI_SEARCH_REFERRALS:
case SLAPI_CHANGENUMBER:
case SLAPI_LOG_OPERATION:
case SLAPI_DBSIZE:
case SLAPI_RESULT_CODE:
case SLAPI_RESULT_TEXT:
case SLAPI_RESULT_MATCHED:
case SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN:
case SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN:
2003-08-31 16:17:21 +08:00
case SLAPI_PLUGIN_ACL_ALLOW_ACCESS:
case SLAPI_X_PLUGIN_PRE_GROUP_FN:
case SLAPI_X_PLUGIN_POST_GROUP_FN:
case SLAPI_X_GROUP_ENTRY:
case SLAPI_X_GROUP_ATTRIBUTE:
case SLAPI_X_GROUP_OPERATION_DN:
case SLAPI_X_GROUP_TARGET_ENTRY:
return LDAP_SUCCESS;
default:
return INVALID_PARAM;
}
}
static int
isValidParam( Slapi_PBlock *pb, int param )
{
if ( pb->ckParams == TRUE ) {
if ( IBM_RESERVED( param ) ) return LDAP_SUCCESS;
if (param == SLAPI_PLUGIN_AUDIT_FN ||
param == SLAPI_PLUGIN_AUDIT_DATA )
return LDAP_SUCCESS;
if ( param < LAST_IBM_PARAM ) {
return INVALID_PARAM;
} else if ( NETSCAPE_RESERVED( param ) ) {
return INVALID_PARAM;
} else {
return isOkNetscapeParam(param);
}
} else {
return LDAP_SUCCESS;
}
}
static void
Lock( Slapi_PBlock *pb )
{
ldap_pvt_thread_mutex_lock(&pb->pblockMutex);
}
static void
unLock( Slapi_PBlock *pb )
{
ldap_pvt_thread_mutex_unlock(&pb->pblockMutex);
}
static int
get( Slapi_PBlock *pb, int param, void **val )
{
int i;
if ( isValidParam( pb, param ) == INVALID_PARAM ) {
return PBLOCK_ERROR;
}
Lock( pb );
*val = NULL;
for ( i = 0; i < pb->numParams; i++ ) {
if ( pb->curParams[i] == param ) {
*val = pb->curVals[i];
break;
}
}
unLock( pb );
return LDAP_SUCCESS;
}
static int
set( Slapi_PBlock *pb, int param, void *val )
{
#if defined(LDAP_SLAPI)
2003-09-24 08:32:27 +08:00
int i, freeit;
int addcon = 0;
if ( isValidParam( pb, param ) == INVALID_PARAM ) {
return PBLOCK_ERROR;
}
Lock( pb );
2003-01-27 22:44:39 +08:00
if ( pb->numParams == PBLOCK_MAX_PARAMS ) {
unLock( pb );
return PBLOCK_ERROR;
}
if ( param == SLAPI_ADD_RESCONTROL ) {
addcon = 1;
param = SLAPI_RES_CONTROLS;
}
2003-09-24 08:32:27 +08:00
switch ( param ) {
case SLAPI_CONN_DN:
case SLAPI_CONN_AUTHMETHOD:
case SLAPI_IBM_CONN_DN_ALT:
case SLAPI_IBM_CONN_DN_ORIG:
case SLAPI_RESULT_TEXT:
case SLAPI_RESULT_MATCHED:
freeit = 1; break;
default:
freeit = 0; break;
}
for( i = 0; i < pb->numParams; i++ ) {
if ( pb->curParams[i] == param ) {
break;
}
}
if ( i >= pb->numParams ) {
pb->curParams[i] = param;
pb->numParams++;
}
if ( addcon ) {
LDAPControl **ctrls = pb->curVals[i];
int j;
2004-03-03 04:31:37 +08:00
if ( ctrls ) {
for (j=0; ctrls[j]; j++);
ctrls = ch_realloc( ctrls, (j+2)*sizeof(LDAPControl *) );
} else {
ctrls = ch_malloc( 2 * sizeof(LDAPControl *) );
j = 0;
}
ctrls[j] = val;
ctrls[j+1] = NULL;
pb->curVals[i] = ctrls;
} else {
if ( freeit ) ch_free( pb->curVals[i] );
pb->curVals[i] = val;
}
unLock( pb );
return LDAP_SUCCESS;
#endif /* LDAP_SLAPI */
return PBLOCK_ERROR;
}
static void
clearPB( Slapi_PBlock *pb )
{
pb->numParams = 1;
}
static void
checkParams( Slapi_PBlock *pb, int flag )
{
pb->ckParams = flag;
}
static int
deleteParam( Slapi_PBlock *p, int param )
{
int i;
Lock(p);
for ( i = 0; i < p->numParams; i++ ) {
if ( p->curParams[i] == param ) {
break;
}
}
if (i >= p->numParams ) {
unLock( p );
return PBLOCK_ERROR;
}
if ( p->numParams > 1 ) {
p->curParams[i] = p->curParams[p->numParams];
p->curVals[i] = p->curVals[p->numParams];
}
p->numParams--;
unLock( p );
return LDAP_SUCCESS;
}
Slapi_PBlock *
slapi_pblock_new()
{
#if defined(LDAP_SLAPI)
Slapi_PBlock *pb;
pb = (Slapi_PBlock *) ch_malloc(sizeof(Slapi_PBlock));
if ( pb != NULL ) {
pb->ckParams = TRUE;
ldap_pvt_thread_mutex_init( &pb->pblockMutex );
memset( pb->curParams, 0, sizeof(pb->curParams) );
memset( pb->curVals, 0, sizeof(pb->curVals) );
pb->curParams[0] = SLAPI_IBM_PBLOCK;
pb->curVals[0] = NULL;
pb->numParams = 1;
}
return pb;
#endif /* LDAP_SLAPI */
return NULL;
}
void
slapi_pblock_destroy( Slapi_PBlock* pb )
{
#if defined(LDAP_SLAPI)
char *str = NULL;
LDAPControl **rescontrols = NULL;
get( pb, SLAPI_CONN_DN,(void **)&str );
if ( str != NULL ) {
ch_free( str );
str = NULL;
}
get( pb, SLAPI_CONN_AUTHMETHOD, (void **)&str );
if ( str != NULL ) {
ch_free( str );
str = NULL;
}
get( pb, SLAPI_IBM_CONN_DN_ALT, (void **)&str );
if ( str != NULL ) {
ch_free( str );
str = NULL;
}
get( pb, SLAPI_IBM_CONN_DN_ORIG, (void **)&str );
if ( str != NULL ) {
ch_free( str );
}
get( pb, SLAPI_RESULT_TEXT, (void **)&str );
if ( str != NULL ) {
ch_free( str );
str = NULL;
}
get( pb, SLAPI_RESULT_MATCHED, (void **)&str );
if ( str != NULL ) {
ch_free( str );
str = NULL;
}
get( pb, SLAPI_RESCONTROLS, (void **)&rescontrols );
if ( rescontrols != NULL ) {
ldap_controls_free( rescontrols );
rescontrols = NULL;
}
ldap_pvt_thread_mutex_destroy( &pb->pblockMutex );
ch_free( pb );
#endif /* LDAP_SLAPI */
}
int
slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value )
{
#if defined(LDAP_SLAPI)
return get( pb, arg, (void **)value );
#endif /* LDAP_SLAPI */
return PBLOCK_ERROR;
}
int
slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value )
{
#if defined(LDAP_SLAPI)
void *pTmp = NULL;
switch ( arg ) {
case SLAPI_CONN_DN:
case SLAPI_CONN_AUTHMETHOD:
case SLAPI_IBM_CONN_DN_ALT:
case SLAPI_IBM_CONN_DN_ORIG:
case SLAPI_RESULT_TEXT:
case SLAPI_RESULT_MATCHED:
if ( value != NULL ) {
pTmp = (void *)slapi_ch_strdup((char *)value);
if ( pTmp == NULL ) {
return LDAP_NO_MEMORY;
}
}
break;
default:
pTmp = value;
break;
}
return set( pb, arg, pTmp );
#endif /* LDAP_SLAPI */
return LDAP_NO_MEMORY;
}
void
slapi_pblock_clear( Slapi_PBlock *pb )
{
#if defined(LDAP_SLAPI)
clearPB( pb );
#endif /* LDAP_SLAPI */
}
int
slapi_pblock_delete_param( Slapi_PBlock *p, int param )
{
#if defined(LDAP_SLAPI)
return deleteParam( p, param );
#endif /* LDAP_SLAPI */
return PBLOCK_ERROR;
}
void
slapi_pblock_check_params( Slapi_PBlock *pb, int flag )
{
#if defined(LDAP_SLAPI)
checkParams( pb, flag );
#endif /* LDAP_SLAPI */
}
/*
* OpenLDAP extension
*/
int
slapi_int_pblock_get_first( Backend *be, Slapi_PBlock **pb )
{
#if defined(LDAP_SLAPI)
assert( pb );
*pb = (Slapi_PBlock *)be->be_pb;
return (*pb == NULL ? LDAP_OTHER : LDAP_SUCCESS);
#else /* LDAP_SLAPI */
return LDAP_OTHER;
#endif /* LDAP_SLAPI */
}
/*
* OpenLDAP extension
*/
int
slapi_int_pblock_get_next( Slapi_PBlock **pb )
{
#if defined(LDAP_SLAPI)
assert( pb );
return slapi_pblock_get( *pb, SLAPI_IBM_PBLOCK, pb );
#else /* LDAP_SLAPI */
return LDAP_OTHER;
#endif /* LDAP_SLAPI */
}