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

📄 rwm.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* rwm.c - rewrite/remap operations *//* $OpenLDAP: pkg/ldap/servers/slapd/overlays/rwm.c,v 1.37.2.18 2007/01/05 09:47:11 ando Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 2003-2007 The OpenLDAP Foundation. * Portions Copyright 2003 Pierangelo Masarati. * 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>. */#include "portable.h"#ifdef SLAPD_OVER_RWM#include <stdio.h>#include <ac/string.h>#include "slap.h"#include "rwm.h"typedef struct rwm_op_state {	ber_tag_t r_tag;	struct berval ro_dn;	struct berval ro_ndn;	struct berval r_dn;	struct berval r_ndn;	OpRequest o_request;} rwm_op_state;static intrwm_db_destroy( BackendDB *be );typedef struct rwm_op_cb {	slap_callback cb;	rwm_op_state ros;} rwm_op_cb;static intrwm_op_cleanup( Operation *op, SlapReply *rs ){	slap_callback	*cb = op->o_callback;	rwm_op_state *ros = cb->sc_private;	if ( rs->sr_type == REP_RESULT || rs->sr_type == REP_EXTENDED ||		op->o_abandon || rs->sr_err == SLAPD_ABANDON ) {		op->o_req_dn = ros->ro_dn;		op->o_req_ndn = ros->ro_ndn;		if ( !BER_BVISEMPTY( &ros->r_dn )) ch_free( ros->r_dn.bv_val );		if ( !BER_BVISEMPTY( &ros->r_ndn )) ch_free( ros->r_ndn.bv_val );		switch( ros->r_tag ) {		case LDAP_REQ_COMPARE:			if ( op->orc_ava->aa_value.bv_val != ros->orc_ava->aa_value.bv_val )				op->o_tmpfree( op->orc_ava->aa_value.bv_val, op->o_tmpmemctx );			op->orc_ava = ros->orc_ava;			break;		case LDAP_REQ_MODIFY:			slap_mods_free( op->orm_modlist, 1 );			op->orm_modlist = ros->orm_modlist;			break;		case LDAP_REQ_MODRDN:			if ( op->orr_newSup != ros->orr_newSup ) {				ch_free( op->orr_newSup->bv_val );				ch_free( op->orr_nnewSup->bv_val );				op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );				op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );				op->orr_newSup = ros->orr_newSup;				op->orr_nnewSup = ros->orr_nnewSup;			}			break;		case LDAP_REQ_SEARCH:			ch_free( op->ors_attrs );			filter_free_x( op, op->ors_filter );			ch_free( op->ors_filterstr.bv_val );			op->ors_attrs = ros->ors_attrs;			op->ors_filter = ros->ors_filter;			op->ors_filterstr = ros->ors_filterstr;			break;		case LDAP_REQ_EXTENDED:			if ( op->ore_reqdata != ros->ore_reqdata ) {				ber_bvfree( op->ore_reqdata );				op->ore_reqdata = ros->ore_reqdata;			}			break;		default:	break;		}		op->o_callback = op->o_callback->sc_next;		op->o_tmpfree( cb, op->o_tmpmemctx );	}	return SLAP_CB_CONTINUE;}static rwm_op_cb *rwm_callback_get( Operation *op, SlapReply *rs ){	rwm_op_cb	*roc = NULL;	roc = op->o_tmpalloc( sizeof( struct rwm_op_cb ), op->o_tmpmemctx );	roc->cb.sc_cleanup = rwm_op_cleanup;	roc->cb.sc_response = NULL;	roc->cb.sc_next = op->o_callback;	roc->cb.sc_private = &roc->ros;	roc->ros.r_tag = op->o_tag;	roc->ros.ro_dn = op->o_req_dn;	roc->ros.ro_ndn = op->o_req_ndn;	roc->ros.o_request = op->o_request;	BER_BVZERO( &roc->ros.r_dn );	BER_BVZERO( &roc->ros.r_ndn );	return roc;}static intrwm_op_dn_massage( Operation *op, SlapReply *rs, void *cookie,	rwm_op_state *ros ){	slap_overinst		*on = (slap_overinst *) op->o_bd->bd_info;	struct ldaprwmap	*rwmap = 			(struct ldaprwmap *)on->on_bi.bi_private;	struct berval		dn = BER_BVNULL,				ndn = BER_BVNULL;	int			rc = 0;	dncookie		dc;	/*	 * Rewrite the dn if needed	 */	dc.rwmap = rwmap;#ifdef ENABLE_REWRITE	dc.conn = op->o_conn;	dc.rs = rs;	dc.ctx = (char *)cookie;#else /* ! ENABLE_REWRITE */	dc.tofrom = ((int *)cookie)[0];	dc.normalized = 0;#endif /* ! ENABLE_REWRITE */	/* NOTE: in those cases where only the ndn is available,	 * and the caller sets op->o_req_dn = op->o_req_ndn,	 * only rewrite the op->o_req_ndn and use it as 	 * op->o_req_dn as well */	ndn = op->o_req_ndn;	if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {		dn = op->o_req_dn;		rc = rwm_dn_massage_pretty_normalize( &dc, &op->o_req_dn, &dn, &ndn );	} else {		rc = rwm_dn_massage_normalize( &dc, &op->o_req_ndn, &ndn );	}	if ( rc != LDAP_SUCCESS ) {		return rc;	}	if ( ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val && dn.bv_val == op->o_req_dn.bv_val )			|| ndn.bv_val == op->o_req_ndn.bv_val )	{		return LDAP_SUCCESS;	}	if ( op->o_req_dn.bv_val != op->o_req_ndn.bv_val ) {		op->o_req_dn = dn;		ros->r_dn  = dn;	} else {		op->o_req_dn = ndn;	}	ros->r_ndn = ndn;	op->o_req_ndn = ndn;	return LDAP_SUCCESS;}static intrwm_op_add( Operation *op, SlapReply *rs ){	slap_overinst		*on = (slap_overinst *) op->o_bd->bd_info;	struct ldaprwmap	*rwmap = 			(struct ldaprwmap *)on->on_bi.bi_private;	int			rc,				i;	Attribute		**ap = NULL;	char			*olddn = op->o_req_dn.bv_val;	int			isupdate;	rwm_op_cb *roc = rwm_callback_get( op, rs );#ifdef ENABLE_REWRITE	rc = rwm_op_dn_massage( op, rs, "addDN", &roc->ros );#else /* ! ENABLE_REWRITE */	rc = 1;	rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );#endif /* ! ENABLE_REWRITE */	if ( rc != LDAP_SUCCESS ) {		op->o_bd->bd_info = (BackendInfo *)on->on_info;		send_ldap_error( op, rs, rc, "addDN massage error" );		return -1;	}	if ( olddn != op->o_req_dn.bv_val ) {		ber_bvreplace( &op->ora_e->e_name, &op->o_req_dn );		ber_bvreplace( &op->ora_e->e_nname, &op->o_req_ndn );	}	/* Count number of attributes in entry */ 	isupdate = be_shadow_update( op );	for ( i = 0, ap = &op->oq_add.rs_e->e_attrs; *ap; ) {		Attribute	*a;		if ( (*ap)->a_desc == slap_schema.si_ad_objectClass ||				(*ap)->a_desc == slap_schema.si_ad_structuralObjectClass )		{			int		j, last;			for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[ last ] ); last++ )					/* count values */ ;			last--;			for ( j = 0; !BER_BVISNULL( &(*ap)->a_vals[ j ] ); j++ ) {				struct ldapmapping	*mapping = NULL;				( void )rwm_mapping( &rwmap->rwm_oc, &(*ap)->a_vals[ j ],						&mapping, RWM_MAP );				if ( mapping == NULL ) {					if ( rwmap->rwm_at.drop_missing ) {						/* FIXME: we allow to remove objectClasses as well;						 * if the resulting entry is inconsistent, that's						 * the relayed database's business...						 */						ch_free( (*ap)->a_vals[ j ].bv_val );						if ( last > j ) {							(*ap)->a_vals[ j ] = (*ap)->a_vals[ last ];						}						BER_BVZERO( &(*ap)->a_vals[ last ] );						last--;						j--;					}				} else {					ch_free( (*ap)->a_vals[ j ].bv_val );					ber_dupbv( &(*ap)->a_vals[ j ], &mapping->m_dst );				}			}		} else if ( !isupdate && !get_manageDIT( op ) && (*ap)->a_desc->ad_type->sat_no_user_mod )		{			goto next_attr;		} else {			struct ldapmapping	*mapping = NULL;			( void )rwm_mapping( &rwmap->rwm_at, &(*ap)->a_desc->ad_cname,					&mapping, RWM_MAP );			if ( mapping == NULL ) {				if ( rwmap->rwm_at.drop_missing ) {					goto cleanup_attr;				}			}			if ( (*ap)->a_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName					|| ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )			{				/*				 * FIXME: rewrite could fail; in this case				 * the operation should give up, right?				 */#ifdef ENABLE_REWRITE				rc = rwm_dnattr_rewrite( op, rs, "addAttrDN",						(*ap)->a_vals,						(*ap)->a_nvals ? &(*ap)->a_nvals : NULL );#else /* ! ENABLE_REWRITE */				rc = 1;				rc = rwm_dnattr_rewrite( op, rs, &rc, (*ap)->a_vals,						(*ap)->a_nvals ? &(*ap)->a_nvals : NULL );#endif /* ! ENABLE_REWRITE */				if ( rc ) {					goto cleanup_attr;				}			} else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {#ifdef ENABLE_REWRITE				rc = rwm_referral_rewrite( op, rs, "referralAttrDN",						(*ap)->a_vals,						(*ap)->a_nvals ? &(*ap)->a_nvals : NULL );#else /* ! ENABLE_REWRITE */				rc = 1;				rc = rwm_referral_rewrite( op, rs, &rc, (*ap)->a_vals,						(*ap)->a_nvals ? &(*ap)->a_nvals : NULL );#endif /* ! ENABLE_REWRITE */				if ( rc != LDAP_SUCCESS ) {					goto cleanup_attr;				}			}					if ( mapping != NULL ) {				assert( mapping->m_dst_ad != NULL );				(*ap)->a_desc = mapping->m_dst_ad;			}		}next_attr:;		ap = &(*ap)->a_next;		continue;cleanup_attr:;		/* FIXME: leaking attribute/values? */		a = *ap;		*ap = (*ap)->a_next;		attr_free( a );	}	op->o_callback = &roc->cb;	return SLAP_CB_CONTINUE;}#ifdef ENABLE_REWRITEstatic intrwm_conn_init( BackendDB *be, Connection *conn ){	slap_overinst		*on = (slap_overinst *) be->bd_info;	struct ldaprwmap	*rwmap = 			(struct ldaprwmap *)on->on_bi.bi_private;	( void )rewrite_session_init( rwmap->rwm_rw, conn );	return SLAP_CB_CONTINUE;}static intrwm_conn_destroy( BackendDB *be, Connection *conn ){	slap_overinst		*on = (slap_overinst *) be->bd_info;	struct ldaprwmap	*rwmap = 			(struct ldaprwmap *)on->on_bi.bi_private;	( void )rewrite_session_delete( rwmap->rwm_rw, conn );	return SLAP_CB_CONTINUE;}#endif /* ENABLE_REWRITE */static intrwm_op_bind( Operation *op, SlapReply *rs ){	slap_overinst		*on = (slap_overinst *) op->o_bd->bd_info;	int			rc;	rwm_op_cb *roc = rwm_callback_get( op, rs );#ifdef ENABLE_REWRITE	rc = rwm_op_dn_massage( op, rs, "bindDN", &roc->ros );#else /* ! ENABLE_REWRITE */	rc = 1;	rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );#endif /* ! ENABLE_REWRITE */	if ( rc != LDAP_SUCCESS ) {		op->o_bd->bd_info = (BackendInfo *)on->on_info;		send_ldap_error( op, rs, rc, "bindDN massage error" );		return -1;	}	op->o_callback = &roc->cb;	return SLAP_CB_CONTINUE;}static intrwm_op_unbind( Operation *op, SlapReply *rs ){	slap_overinst		*on = (slap_overinst *) op->o_bd->bd_info;	struct ldaprwmap	*rwmap = 			(struct ldaprwmap *)on->on_bi.bi_private;#ifdef ENABLE_REWRITE	rewrite_session_delete( rwmap->rwm_rw, op->o_conn );#endif /* ENABLE_REWRITE */	return SLAP_CB_CONTINUE;}static intrwm_op_compare( Operation *op, SlapReply *rs ){	slap_overinst		*on = (slap_overinst *) op->o_bd->bd_info;	struct ldaprwmap	*rwmap = 			(struct ldaprwmap *)on->on_bi.bi_private;	int			rc;	struct berval mapped_vals[2] = { BER_BVNULL, BER_BVNULL };	rwm_op_cb *roc = rwm_callback_get( op, rs );#ifdef ENABLE_REWRITE	rc = rwm_op_dn_massage( op, rs, "compareDN", &roc->ros );#else /* ! ENABLE_REWRITE */	rc = 1;	rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );#endif /* ! ENABLE_REWRITE */	if ( rc != LDAP_SUCCESS ) {		op->o_bd->bd_info = (BackendInfo *)on->on_info;		send_ldap_error( op, rs, rc, "compareDN massage error" );		return -1;	}	/* if the attribute is an objectClass, try to remap its value */	if ( op->orc_ava->aa_desc == slap_schema.si_ad_objectClass			|| op->orc_ava->aa_desc == slap_schema.si_ad_structuralObjectClass )	{		rwm_map( &rwmap->rwm_oc, &op->orc_ava->aa_value,				&mapped_vals[0], RWM_MAP );		if ( BER_BVISNULL( &mapped_vals[0] ) || BER_BVISEMPTY( &mapped_vals[0] ) )		{			op->o_bd->bd_info = (BackendInfo *)on->on_info;			send_ldap_error( op, rs, LDAP_OTHER, "compare objectClass map error" );			return -1;		} else if ( mapped_vals[0].bv_val != op->orc_ava->aa_value.bv_val ) {			ber_dupbv_x( &op->orc_ava->aa_value, &mapped_vals[0],				op->o_tmpmemctx );		}	} else {		struct ldapmapping	*mapping = NULL;		AttributeDescription	*ad = op->orc_ava->aa_desc;		( void )rwm_mapping( &rwmap->rwm_at, &op->orc_ava->aa_desc->ad_cname,				&mapping, RWM_MAP );		if ( mapping == NULL ) {			if ( rwmap->rwm_at.drop_missing ) {				op->o_bd->bd_info = (BackendInfo *)on->on_info;				send_ldap_error( op, rs, LDAP_OTHER, "compare attributeType map error" );				return -1;			}		} else {			assert( mapping->m_dst_ad != NULL );			ad = mapping->m_dst_ad;		}		if ( op->orc_ava->aa_desc->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName				|| ( mapping != NULL && mapping->m_dst_ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName ) )		{			struct berval	*mapped_valsp[2];						mapped_valsp[0] = &mapped_vals[0];			mapped_valsp[1] = &mapped_vals[1];			mapped_vals[0] = op->orc_ava->aa_value;#ifdef ENABLE_REWRITE			rc = rwm_dnattr_rewrite( op, rs, "compareAttrDN", NULL, mapped_valsp );#else /* ! ENABLE_REWRITE */			rc = 1;			rc = rwm_dnattr_rewrite( op, rs, &rc, NULL, mapped_valsp );#endif /* ! ENABLE_REWRITE */			if ( rc != LDAP_SUCCESS ) {				op->o_bd->bd_info = (BackendInfo *)on->on_info;				send_ldap_error( op, rs, rc, "compareAttrDN massage error" );				return -1;			}			if ( mapped_vals[ 0 ].bv_val != op->orc_ava->aa_value.bv_val ) {				/* NOTE: if we get here, rwm_dnattr_rewrite()				 * already freed the old value, so now 				 * it's invalid */				ber_dupbv_x( &op->orc_ava->aa_value, &mapped_vals[0],					op->o_tmpmemctx );				ber_memfree_x( mapped_vals[ 0 ].bv_val, NULL );			}		}		op->orc_ava->aa_desc = ad;	}	op->o_callback = &roc->cb;	return SLAP_CB_CONTINUE;}static intrwm_op_delete( Operation *op, SlapReply *rs ){	slap_overinst		*on = (slap_overinst *) op->o_bd->bd_info;	int			rc;	rwm_op_cb *roc = rwm_callback_get( op, rs );#ifdef ENABLE_REWRITE	rc = rwm_op_dn_massage( op, rs, "deleteDN", &roc->ros );#else /* ! ENABLE_REWRITE */	rc = 1;	rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );#endif /* ! ENABLE_REWRITE */	if ( rc != LDAP_SUCCESS ) {		op->o_bd->bd_info = (BackendInfo *)on->on_info;		send_ldap_error( op, rs, rc, "deleteDN massage error" );		return -1;	}	op->o_callback = &roc->cb;	return SLAP_CB_CONTINUE;}static intrwm_op_modify( Operation *op, SlapReply *rs ){	slap_overinst		*on = (slap_overinst *) op->o_bd->bd_info;	struct ldaprwmap	*rwmap = 			(struct ldaprwmap *)on->on_bi.bi_private;	int			isupdate;	Modifications		**mlp;	int			rc;	rwm_op_cb *roc = rwm_callback_get( op, rs );#ifdef ENABLE_REWRITE	rc = rwm_op_dn_massage( op, rs, "modifyDN", &roc->ros );#else /* ! ENABLE_REWRITE */	rc = 1;	rc = rwm_op_dn_massage( op, rs, &rc, &roc->ros );#endif /* ! ENABLE_REWRITE */	if ( rc != LDAP_SUCCESS ) {		op->o_bd->bd_info = (BackendInfo *)on->on_info;		send_ldap_error( op, rs, rc, "modifyDN massage error" );		return -1;	}	isupdate = be_shadow_update( op );	for ( mlp = &op->oq_modify.rs_modlist; *mlp; ) {		int			is_oc = 0;		Modifications		*ml;		struct ldapmapping	*mapping = NULL;		/* duplicate the modlist */		ml = ch_malloc( sizeof( Modifications ));		*ml = **mlp;		*mlp = ml;		if ( ml->sml_desc == slap_schema.si_ad_objectClass 				|| ml->sml_desc == slap_schema.si_ad_structuralObjectClass )		{			is_oc = 1;		} else if ( !isupdate && !get_manageDIT( op ) && (*mlp)->sml_desc->ad_type->sat_no_user_mod  )		{			goto next_mod;		} else {			int			drop_missing;			drop_missing = rwm_mapping( &rwmap->rwm_at,					&ml->sml_desc->ad_cname,					&mapping, RWM_MAP );			if ( drop_missing || ( mapping != NULL && BER_BVISNULL( &mapping->m_dst ) ) )			{				goto cleanup_mod;			}		}		if ( ml->sml_values != NULL ) {			int i, num;			struct berval *bva;			for ( num = 0; !BER_BVISNULL( &ml->sml_values[ num ] ); num++ )				/* count values */ ;			bva = ch_malloc( (num+1) * sizeof( struct berval ));			for (i=0; i<num; i++)				ber_dupbv( &bva[i], &ml->sml_values[i] );			BER_BVZERO( &bva[i] );			ml->sml_values = bva;			if ( ml->sml_nvalues ) {

⌨️ 快捷键说明

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