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

📄 retcode.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* retcode.c - customizable response for client testing purposes *//* $OpenLDAP: pkg/ldap/servers/slapd/overlays/retcode.c,v 1.4.2.9 2007/01/02 21:44:08 kurt Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 2005-2007 The OpenLDAP Foundation. * Portions Copyright 2005 Pierangelo Masarati <ando@sys-net.it> * 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 Pierangelo Masarati for inclusion * in OpenLDAP Software. */#include "portable.h"#ifdef SLAPD_OVER_RETCODE#include <stdio.h>#include <ac/unistd.h>#include <ac/string.h>#include <ac/ctype.h>#include <ac/socket.h>#include "slap.h"#include "lutil.h"static slap_overinst		retcode;static AttributeDescription	*ad_errCode;static AttributeDescription	*ad_errText;static AttributeDescription	*ad_errOp;static AttributeDescription	*ad_errSleepTime;static AttributeDescription	*ad_errMatchedDN;static ObjectClass		*oc_errAbsObject;static ObjectClass		*oc_errObject;static ObjectClass		*oc_errAuxObject;typedef enum retcode_op_e {	SN_DG_OP_NONE		= 0x0000,	SN_DG_OP_ADD		= 0x0001,	SN_DG_OP_BIND		= 0x0002,	SN_DG_OP_COMPARE	= 0x0004,	SN_DG_OP_DELETE		= 0x0008,	SN_DG_OP_MODIFY		= 0x0010,	SN_DG_OP_RENAME		= 0x0020,	SN_DG_OP_SEARCH		= 0x0040,	SN_DG_EXTENDED		= 0x0080,	SN_DG_OP_AUTH		= SN_DG_OP_BIND,	SN_DG_OP_READ		= (SN_DG_OP_COMPARE|SN_DG_OP_SEARCH),	SN_DG_OP_WRITE		= (SN_DG_OP_ADD|SN_DG_OP_DELETE|SN_DG_OP_MODIFY|SN_DG_OP_RENAME),	SN_DG_OP_ALL		= (SN_DG_OP_AUTH|SN_DG_OP_READ|SN_DG_OP_WRITE|SN_DG_EXTENDED)} retcode_op_e;typedef struct retcode_item_t {	struct berval		rdi_dn;	struct berval		rdi_ndn;	struct berval		rdi_text;	struct berval		rdi_matched;	int			rdi_err;	BerVarray		rdi_ref;	int			rdi_sleeptime;	Entry			rdi_e;	slap_mask_t		rdi_mask;	struct retcode_item_t	*rdi_next;} retcode_item_t;typedef struct retcode_t {	struct berval		rd_pdn;	struct berval		rd_npdn;	int			rd_sleep;	retcode_item_t		*rd_item;	unsigned		rd_flags;#define	RETCODE_FNONE		0x00#define	RETCODE_FINDIR		0x01#define	RETCODE_INDIR( rd )	( (rd)->rd_flags & RETCODE_FINDIR )} retcode_t;static intretcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e );static intretcode_cleanup_cb( Operation *op, SlapReply *rs ){	rs->sr_matched = NULL;	rs->sr_text = NULL;	if ( rs->sr_ref != NULL ) {		ber_bvarray_free( rs->sr_ref );		rs->sr_ref = NULL;	}	ch_free( op->o_callback );	op->o_callback = NULL;	return SLAP_CB_CONTINUE;}static intretcode_send_onelevel( Operation *op, SlapReply *rs ){	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;	retcode_t	*rd = (retcode_t *)on->on_bi.bi_private;	retcode_item_t	*rdi;		for ( rdi = rd->rd_item; rdi != NULL; rdi = rdi->rdi_next ) {		if ( op->o_abandon ) {			return rs->sr_err = SLAPD_ABANDON;		}		rs->sr_err = test_filter( op, &rdi->rdi_e, op->ors_filter );		if ( rs->sr_err == LDAP_COMPARE_TRUE ) {			if ( op->ors_slimit == rs->sr_nentries ) {				rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;				goto done;			}			/* safe default */			rs->sr_attrs = op->ors_attrs;			rs->sr_operational_attrs = NULL;			rs->sr_ctrls = NULL;			rs->sr_flags = 0;			rs->sr_err = LDAP_SUCCESS;			rs->sr_entry = &rdi->rdi_e;			rs->sr_err = send_search_entry( op, rs );			rs->sr_entry = NULL;			switch ( rs->sr_err ) {			case LDAP_UNAVAILABLE:	/* connection closed */				rs->sr_err = LDAP_OTHER;				/* fallthru */			case LDAP_SIZELIMIT_EXCEEDED:				goto done;			}		}		rs->sr_err = LDAP_SUCCESS;	}done:;	send_ldap_result( op, rs );	return rs->sr_err;}static intretcode_op_add( Operation *op, SlapReply *rs ){	return retcode_entry_response( op, rs, NULL, op->ora_e );}typedef struct retcode_cb_t {	BackendInfo	*rdc_info;	unsigned	rdc_flags;	ber_tag_t	rdc_tag;	AttributeName	*rdc_attrs;} retcode_cb_t;static intretcode_cb_response( Operation *op, SlapReply *rs ){	retcode_cb_t	*rdc = (retcode_cb_t *)op->o_callback->sc_private;	if ( rs->sr_type == REP_SEARCH ) {		ber_tag_t	o_tag = op->o_tag;		int		rc;		op->o_tag = rdc->rdc_tag;		if ( op->o_tag == LDAP_REQ_SEARCH ) {			rs->sr_attrs = rdc->rdc_attrs;		}		rc = retcode_entry_response( op, rs, rdc->rdc_info, rs->sr_entry );		op->o_tag = o_tag;		return rc;	}	if ( rs->sr_err == LDAP_SUCCESS ) {		if ( !op->o_abandon ) {			rdc->rdc_flags = SLAP_CB_CONTINUE;		}		return 0;	}	return SLAP_CB_CONTINUE;}static intretcode_op_internal( Operation *op, SlapReply *rs ){	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;	Operation	op2 = *op;	BackendDB	db = *op->o_bd;	slap_callback	sc = { 0 };	retcode_cb_t	rdc;	int		rc;	op2.o_tag = LDAP_REQ_SEARCH;	op2.ors_scope = LDAP_SCOPE_BASE;	op2.ors_deref = LDAP_DEREF_NEVER;	op2.ors_tlimit = SLAP_NO_LIMIT;	op2.ors_slimit = SLAP_NO_LIMIT;	op2.ors_limit = NULL;	op2.ors_attrsonly = 0;	op2.ors_attrs = slap_anlist_all_attributes;	ber_str2bv_x( "(objectClass=errAbsObject)",		STRLENOF( "(objectClass=errAbsObject)" ),		1, &op2.ors_filterstr, op2.o_tmpmemctx );	op2.ors_filter = str2filter_x( &op2, op2.ors_filterstr.bv_val );	db.bd_info = on->on_info->oi_orig;	op2.o_bd = &db;	rdc.rdc_info = on->on_info->oi_orig;	rdc.rdc_flags = RETCODE_FINDIR;	if ( op->o_tag == LDAP_REQ_SEARCH ) {		rdc.rdc_attrs = op->ors_attrs;	}	rdc.rdc_tag = op->o_tag;	sc.sc_response = retcode_cb_response;	sc.sc_private = &rdc;	op2.o_callback = &sc;	rc = op2.o_bd->be_search( &op2, rs );	op->o_abandon = op2.o_abandon;	filter_free_x( &op2, op2.ors_filter );	ber_memfree_x( op2.ors_filterstr.bv_val, op2.o_tmpmemctx );	if ( rdc.rdc_flags == SLAP_CB_CONTINUE ) {		return SLAP_CB_CONTINUE;	}	return rc;}static intretcode_op_func( Operation *op, SlapReply *rs ){	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;	retcode_t	*rd = (retcode_t *)on->on_bi.bi_private;	retcode_item_t	*rdi;	struct berval		nrdn, npdn;	slap_callback		*cb = NULL;	/* sleep as required */	if ( rd->rd_sleep < 0 ) {		sleep( rand() % ( - rd->rd_sleep ) );	} else if ( rd->rd_sleep > 0 ) {		sleep( rd->rd_sleep );	}	if ( !dnIsSuffix( &op->o_req_ndn, &rd->rd_npdn ) ) {		if ( RETCODE_INDIR( rd ) ) {			switch ( op->o_tag ) {			case LDAP_REQ_ADD:				return retcode_op_add( op, rs );			case LDAP_REQ_BIND:				/* skip if rootdn */				if ( be_isroot_pw( op ) ) {					return SLAP_CB_CONTINUE;				}				return retcode_op_internal( op, rs );			case LDAP_REQ_SEARCH:				if ( op->ors_scope == LDAP_SCOPE_BASE ) {					rs->sr_err = retcode_op_internal( op, rs );					switch ( rs->sr_err ) {					case SLAP_CB_CONTINUE:						if ( rs->sr_nentries == 0 ) {							break;						}						rs->sr_err = LDAP_SUCCESS;						/* fallthru */					default:						send_ldap_result( op, rs );						break;					}					return rs->sr_err;				}				break;			case LDAP_REQ_MODIFY:			case LDAP_REQ_DELETE:			case LDAP_REQ_MODRDN:			case LDAP_REQ_COMPARE:				return retcode_op_internal( op, rs );			}		}		return SLAP_CB_CONTINUE;	}	if ( op->o_tag == LDAP_REQ_SEARCH			&& op->ors_scope != LDAP_SCOPE_BASE			&& op->o_req_ndn.bv_len == rd->rd_npdn.bv_len )	{		return retcode_send_onelevel( op, rs );	}	dnParent( &op->o_req_ndn, &npdn );	if ( npdn.bv_len != rd->rd_npdn.bv_len ) {		rs->sr_err = LDAP_NO_SUCH_OBJECT;		rs->sr_matched = rd->rd_pdn.bv_val;		send_ldap_result( op, rs );		rs->sr_matched = NULL;		return rs->sr_err;	}	dnRdn( &op->o_req_ndn, &nrdn );	for ( rdi = rd->rd_item; rdi != NULL; rdi = rdi->rdi_next ) {		struct berval	rdi_nrdn;		dnRdn( &rdi->rdi_ndn, &rdi_nrdn );		if ( dn_match( &nrdn, &rdi_nrdn ) ) {			break;		}	}	if ( rdi != NULL && rdi->rdi_mask != SN_DG_OP_ALL ) {		retcode_op_e	o_tag = SN_DG_OP_NONE;		switch ( op->o_tag ) {		case LDAP_REQ_ADD:			o_tag = SN_DG_OP_ADD;			break;		case LDAP_REQ_BIND:			o_tag = SN_DG_OP_BIND;			break;		case LDAP_REQ_COMPARE:			o_tag = SN_DG_OP_COMPARE;			break;		case LDAP_REQ_DELETE:			o_tag = SN_DG_OP_DELETE;			break;		case LDAP_REQ_MODIFY:			o_tag = SN_DG_OP_MODIFY;			break;		case LDAP_REQ_MODRDN:			o_tag = SN_DG_OP_RENAME;			break;		case LDAP_REQ_SEARCH:			o_tag = SN_DG_OP_SEARCH;			break;		case LDAP_REQ_EXTENDED:			o_tag = SN_DG_EXTENDED;			break;		default:			/* Should not happen */			break;		}		if ( !( o_tag & rdi->rdi_mask ) ) {			return SLAP_CB_CONTINUE;		}	}	if ( rdi == NULL ) {		rs->sr_matched = rd->rd_pdn.bv_val;		rs->sr_err = LDAP_NO_SUCH_OBJECT;		rs->sr_text = "retcode not found";	} else {		rs->sr_err = rdi->rdi_err;		rs->sr_text = rdi->rdi_text.bv_val;		rs->sr_matched = rdi->rdi_matched.bv_val;		/* FIXME: we only honor the rdi_ref field in case rdi_err		 * is LDAP_REFERRAL otherwise send_ldap_result() bails out */		if ( rs->sr_err == LDAP_REFERRAL ) {			BerVarray	ref;			if ( rdi->rdi_ref != NULL ) {				ref = rdi->rdi_ref;			} else {				ref = default_referral;			}			if ( ref != NULL ) {				rs->sr_ref = referral_rewrite( ref,					NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );			} else {				rs->sr_err = LDAP_OTHER;				rs->sr_text = "bad referral object";			}		}		if ( rdi->rdi_sleeptime > 0 ) {			sleep( rdi->rdi_sleeptime );		}	}	switch ( op->o_tag ) {	case LDAP_REQ_EXTENDED:		if ( rdi == NULL ) {			break;		}		cb = ( slap_callback * )ch_malloc( sizeof( slap_callback ) );

⌨️ 快捷键说明

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