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

📄 slapi_overlay.c

📁 OpenLdap是LDAP的开源项目
💻 C
📖 第 1 页 / 共 2 页
字号:
/* slapi_overlay.c - SLAPI overlay *//* $OpenLDAP: pkg/ldap/servers/slapd/slapi/slapi_overlay.c,v 1.34.2.6 2007/01/02 21:44:11 kurt Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 2001-2007 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted only as authorized by the OpenLDAP * 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 Luke Howard for inclusion * in OpenLDAP Software. */#include "portable.h"#include <stdio.h>#include <ac/string.h>#include <ac/socket.h>#include "slap.h"#include "slapi.h"#ifdef LDAP_SLAPIstatic slap_overinst slapi;static int slapi_over_initialized = 0;static int slapi_over_response( Operation *op, SlapReply *rs );static int slapi_over_cleanup( Operation *op, SlapReply *rs );static Slapi_PBlock *slapi_over_pblock_new( Operation *op, SlapReply *rs ){	Slapi_PBlock		*pb;	pb = slapi_pblock_new();	pb->pb_op = op;	pb->pb_conn = op->o_conn;	pb->pb_rs = rs;	pb->pb_intop = 0;	PBLOCK_ASSERT_OP( pb, op->o_tag );	return pb;}static intslapi_op_internal_p( Operation *op, SlapReply *rs, slap_callback *cb ){	int			internal_op = 0;	Slapi_PBlock		*pb = NULL;	slap_callback		*pcb;	/*	 * Abstraction violating check for SLAPI internal operations	 * allows pblock to remain consistent when invoking internal	 * op plugins	 */	for ( pcb = op->o_callback; pcb != NULL; pcb = pcb->sc_next ) {		if ( pcb->sc_response == slapi_int_response ) {			pb = (Slapi_PBlock *)pcb->sc_private;			PBLOCK_ASSERT_INTOP( pb, 0 );			internal_op = 1;			break;		}	}	if ( cb != NULL ) {		if ( pb == NULL ) {			pb = slapi_over_pblock_new( op, rs );		}		cb->sc_response = slapi_over_response;		cb->sc_cleanup = slapi_over_cleanup;		cb->sc_private = pb;		cb->sc_next = op->o_callback;		op->o_callback = cb;	}	return internal_op;}static intslapi_over_compute_output(	computed_attr_context *c,	Slapi_Attr *attribute,	Slapi_Entry *entry){	Attribute		**a;	AttributeDescription	*desc;	SlapReply		*rs = (SlapReply *)c->cac_private;	if ( c == NULL || attribute == NULL || entry == NULL ) {		return 0;	}	assert( rs->sr_entry == entry );	desc = attribute->a_desc;	if ( rs->sr_attrs == NULL ) {		/* All attrs request, skip operational attributes */		if ( is_at_operational( desc->ad_type ) ) {			return 0;		}	} else {		/* Specific attributes requested */		if ( is_at_operational( desc->ad_type ) ) {			if ( !SLAP_OPATTRS( rs->sr_attr_flags ) &&			     !ad_inlist( desc, rs->sr_attrs ) ) {				return 0;			}		} else {			if ( !SLAP_USERATTRS( rs->sr_attr_flags ) &&			     !ad_inlist( desc, rs->sr_attrs ) ) {				return 0;			}		}	}	/* XXX perhaps we should check for existing attributes and merge */	for ( a = &rs->sr_operational_attrs; *a != NULL; a = &(*a)->a_next )		;	*a = slapi_attr_dup( attribute );	return 0;}static intslapi_over_aux_operational( Operation *op, SlapReply *rs ){	/* Support for computed attribute plugins */	computed_attr_context    ctx;	AttributeName		*anp;	if ( slapi_op_internal_p( op, rs, NULL ) ) {		return SLAP_CB_CONTINUE;	}	ctx.cac_pb = slapi_over_pblock_new( op, rs );	ctx.cac_op = op;	ctx.cac_private = rs;	if ( rs->sr_entry != NULL ) {		/*		 * For each client requested attribute, call the plugins.		 */		if ( rs->sr_attrs != NULL ) {			for ( anp = rs->sr_attrs; anp->an_name.bv_val != NULL; anp++ ) {				if ( compute_evaluator( &ctx, anp->an_name.bv_val,					rs->sr_entry, slapi_over_compute_output ) == 1 ) {					break;				}			}		} else {			/*			 * Technically we shouldn't be returning operational attributes			 * when the user requested only user attributes. We'll let the			 * plugin decide whether to be naughty or not.			 */			compute_evaluator( &ctx, "*", rs->sr_entry, slapi_over_compute_output );		}	}	slapi_pblock_destroy( ctx.cac_pb );	return SLAP_CB_CONTINUE;}/* * We need this function to call frontendDB (global) plugins before * database plugins, if we are invoked by a slap_callback. */static intslapi_over_call_plugins( Slapi_PBlock *pb, int type ){	int 			rc = 1; /* means no plugins called */	Operation		*op;	PBLOCK_ASSERT_OP( pb, 0 );	op = pb->pb_op;	if ( !be_match( op->o_bd, frontendDB ) ) {		rc = slapi_int_call_plugins( frontendDB, type, pb );	}	if ( rc >= 0 ) {		rc = slapi_int_call_plugins( op->o_bd, type, pb );	}	return rc;}static intslapi_over_search( Operation *op, SlapReply *rs, int type ){	int			rc;	Slapi_PBlock		*pb;	assert( rs->sr_type == REP_SEARCH || rs->sr_type == REP_SEARCHREF );	/* create a new pblock to not trample on result controls */	pb = slapi_over_pblock_new( op, rs );	rc = slapi_over_call_plugins( pb, type );	if ( rc >= 0 ) /* 1 means no plugins called */		rc = SLAP_CB_CONTINUE;	else		rc = LDAP_SUCCESS; /* confusing: don't abort, but don't send */	slapi_pblock_destroy(pb);	return rc;}/* * Call pre- and post-result plugins */static intslapi_over_result( Operation *op, SlapReply *rs, int type ){	Slapi_PBlock		*pb = SLAPI_OPERATION_PBLOCK( op );	assert( rs->sr_type == REP_RESULT );	slapi_over_call_plugins( pb, type );	return SLAP_CB_CONTINUE;}static intslapi_op_bind_callback( Operation *op, SlapReply *rs, int prc ){	switch ( prc ) {	case SLAPI_BIND_SUCCESS:		/* Continue with backend processing */		break;	case SLAPI_BIND_FAIL:		/* Failure, frontend (that's us) sends result */		rs->sr_err = LDAP_INVALID_CREDENTIALS;		send_ldap_result( op, rs );		return rs->sr_err;		break;	case SLAPI_BIND_ANONYMOUS: /* undocumented */	default: /* plugin sent result or no plugins called */		BER_BVZERO( &op->orb_edn );		if ( rs->sr_err == LDAP_SUCCESS ) {			/*			 * Plugin will have called slapi_pblock_set(LDAP_CONN_DN) which			 * will have set conn->c_dn and conn->c_ndn			 */			if ( BER_BVISNULL( &op->o_conn->c_ndn ) && prc == 1 ) {				/* No plugins were called; continue processing */				return LDAP_SUCCESS;			}			ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );			if ( !BER_BVISEMPTY( &op->o_conn->c_ndn ) ) {				ber_len_t max = sockbuf_max_incoming_auth;				ber_sockbuf_ctrl( op->o_conn->c_sb,					LBER_SB_OPT_SET_MAX_INCOMING, &max );			}			ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );			/* log authorization identity */			Statslog( LDAP_DEBUG_STATS,				"%s BIND dn=\"%s\" mech=%s (SLAPI) ssf=0\n",				op->o_log_prefix,				BER_BVISNULL( &op->o_conn->c_dn )					? "<empty>" : op->o_conn->c_dn.bv_val,				BER_BVISNULL( &op->orb_tmp_mech )					? "<empty>" : op->orb_tmp_mech.bv_val, 0, 0 );			return -1;		}		break;	}	return rs->sr_err;}static intslapi_op_search_callback( Operation *op, SlapReply *rs, int prc ){	Slapi_PBlock		*pb = SLAPI_OPERATION_PBLOCK( op );	/* check preoperation result code */	if ( prc < 0 ) {		return rs->sr_err;	}	rs->sr_err = LDAP_SUCCESS;	if ( slapi_int_call_plugins( op->o_bd, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb ) == 0 ) {		/*		 * The plugin can set the SLAPI_SEARCH_FILTER.		 * SLAPI_SEARCH_STRFILER is not normative.		 */		op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );		filter2bv_x( op, op->ors_filter, &op->ors_filterstr );	}	return LDAP_SUCCESS;}struct slapi_op_info {	int soi_preop;			/* preoperation plugin parameter */	int soi_postop;			/* postoperation plugin parameter */	int soi_internal_preop;		/* internal preoperation plugin parameter */	int soi_internal_postop;	/* internal postoperation plugin parameter */	int (*soi_callback)(Operation *, SlapReply *, int); /* preoperation result handler */} slapi_op_dispatch_table[] = {	{		SLAPI_PLUGIN_PRE_BIND_FN,		SLAPI_PLUGIN_POST_BIND_FN,		0,		0,		slapi_op_bind_callback	},	{		SLAPI_PLUGIN_PRE_UNBIND_FN,		SLAPI_PLUGIN_POST_UNBIND_FN,		0,		0,		NULL	},	{		SLAPI_PLUGIN_PRE_SEARCH_FN,		SLAPI_PLUGIN_POST_SEARCH_FN,		0,		0,		slapi_op_search_callback	},	{		SLAPI_PLUGIN_PRE_COMPARE_FN,		SLAPI_PLUGIN_POST_COMPARE_FN,		0,		0,		NULL	},	{		SLAPI_PLUGIN_PRE_MODIFY_FN,		SLAPI_PLUGIN_POST_MODIFY_FN,		SLAPI_PLUGIN_INTERNAL_PRE_MODIFY_FN,		SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN,		NULL	},	{		SLAPI_PLUGIN_PRE_MODRDN_FN,		SLAPI_PLUGIN_POST_MODRDN_FN,		SLAPI_PLUGIN_INTERNAL_PRE_MODRDN_FN,		SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN,		NULL	},	{		SLAPI_PLUGIN_PRE_ADD_FN,		SLAPI_PLUGIN_POST_ADD_FN,		SLAPI_PLUGIN_INTERNAL_PRE_ADD_FN,		SLAPI_PLUGIN_INTERNAL_POST_ADD_FN,		NULL	},	{		SLAPI_PLUGIN_PRE_DELETE_FN,		SLAPI_PLUGIN_POST_DELETE_FN,		SLAPI_PLUGIN_INTERNAL_PRE_DELETE_FN,		SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN,		NULL	},	{		SLAPI_PLUGIN_PRE_ABANDON_FN,		SLAPI_PLUGIN_POST_ABANDON_FN,		0,		0,		NULL	},	{		0,		0,		0,		0,		NULL	}};slap_operation_tslapi_tag2op( ber_tag_t tag ){	slap_operation_t op;	switch ( tag ) {	case LDAP_REQ_BIND:		op = op_bind;		break;	case LDAP_REQ_ADD:		op = op_add;		break;	case LDAP_REQ_DELETE:		op = op_delete;		break;	case LDAP_REQ_MODRDN:		op = op_modrdn;		break;	case LDAP_REQ_MODIFY:		op = op_modify;		break;	case LDAP_REQ_COMPARE:		op = op_compare;		break;	case LDAP_REQ_SEARCH:		op = op_search;		break;	case LDAP_REQ_UNBIND:		op = op_unbind;		break;	default:		op = op_last;		break;	}	return op;}/* Add SLAPI_RESCONTROLS to rs->sr_ctrls, with care, because * rs->sr_ctrls could be allocated on the stack */static intslapi_over_merge_controls( Operation *op, SlapReply *rs ){	Slapi_PBlock		*pb = SLAPI_OPERATION_PBLOCK( op );	LDAPControl		**ctrls = NULL;	LDAPControl		**slapi_ctrls = NULL;	size_t			n_slapi_ctrls = 0;	size_t			n_rs_ctrls = 0;	size_t			i;	slapi_pblock_get( pb, SLAPI_RESCONTROLS, (void **)&slapi_ctrls );	n_slapi_ctrls = slapi_int_count_controls( slapi_ctrls );	n_rs_ctrls = slapi_int_count_controls( rs->sr_ctrls );	slapi_pblock_set( pb, SLAPI_X_OLD_RESCONTROLS, (void *)rs->sr_ctrls );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -