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

📄 translucent.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* translucent.c - translucent proxy module *//* $OpenLDAP: pkg/ldap/servers/slapd/overlays/translucent.c,v 1.1.2.13 2007/01/02 21:44:09 kurt Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 2004-2007 The OpenLDAP Foundation. * Portions Copyright 2005 Symas Corporation. * 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 Symas Corp. for inclusion in * OpenLDAP Software.  This work was sponsored by Hewlett-Packard. */#include "portable.h"#ifdef SLAPD_OVER_TRANSLUCENT#include <stdio.h>#include <ac/string.h>#include <ac/socket.h>#include "slap.h"#include "lutil.h"/* config block */typedef struct translucent_configuration {	int debug;	int strict;	int no_add;	int glue;} translucent_configuration;/* stack of captive backends */typedef struct overlay_stack {	BackendInfo *info;			/* captive backend */	void *private;				/* local backend_private */	translucent_configuration *config;	/* our_private: configuration */} overlay_stack;/* for translucent_init() */static slap_overinst translucent;/*** glue_parent()**	call syncrepl_add_glue() with the parent suffix;***/static struct berval glue[] = { BER_BVC("top"), BER_BVC("glue"), BER_BVNULL };void glue_parent(Operation *op) {	Operation nop = *op;	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;	struct berval ndn = BER_BVNULL;	Attribute *a;	Entry *e;	struct berval	pdn;	dnParent( &op->o_req_ndn, &pdn );	ber_dupbv_x( &ndn, &pdn, op->o_tmpmemctx );	Debug(LDAP_DEBUG_TRACE, "=> glue_parent: fabricating glue for <%s>\n", ndn.bv_val, 0, 0);	e = ch_calloc(1, sizeof(Entry));	e->e_id = NOID;	ber_dupbv(&e->e_name, &ndn);	ber_dupbv(&e->e_nname, &ndn);	a = ch_calloc(1, sizeof(Attribute));	a->a_desc = slap_schema.si_ad_objectClass;	a->a_vals = ch_malloc(sizeof(struct berval) * 3);	ber_dupbv(&a->a_vals[0], &glue[0]);	ber_dupbv(&a->a_vals[1], &glue[1]);	ber_dupbv(&a->a_vals[2], &glue[2]);	a->a_nvals = a->a_vals;	a->a_next = e->e_attrs;	e->e_attrs = a;	a = ch_calloc(1, sizeof(Attribute));	a->a_desc = slap_schema.si_ad_structuralObjectClass;	a->a_vals = ch_malloc(sizeof(struct berval) * 2);	ber_dupbv(&a->a_vals[0], &glue[1]);	ber_dupbv(&a->a_vals[1], &glue[2]);	a->a_nvals = a->a_vals;	a->a_next = e->e_attrs;	e->e_attrs = a;	nop.o_req_dn = ndn;	nop.o_req_ndn = ndn;	nop.ora_e = e;	nop.o_bd->bd_info = (BackendInfo *) on->on_info->oi_orig;	syncrepl_add_glue(&nop, e);	op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );	return;}/*** dup_bervarray()**	copy a BerVarray;*/BerVarray dup_bervarray(BerVarray b) {	int i, len;	BerVarray nb;	for(len = 0; b[len].bv_val; len++);	nb = ch_malloc((len+1) * sizeof(BerValue));	for(i = 0; i < len; i++) ber_dupbv(&nb[i], &b[i]);	nb[len].bv_val = NULL;	nb[len].bv_len = 0;	return(nb);}/*** free_attr_chain()**	free only the Attribute*, not the contents;***/void free_attr_chain(Attribute *a) {	Attribute *ax;	for(; a; a = ax) {		ax = a->a_next;		ch_free(a);	}	return;}/*** translucent_add()**	if not bound as root, send ACCESS error;**	if config.glue, glue_parent();**	return CONTINUE;***/static int translucent_add(Operation *op, SlapReply *rs) {	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;	overlay_stack *ov = on->on_bi.bi_private;	Debug(LDAP_DEBUG_TRACE, "==> translucent_add: %s\n",		op->o_req_dn.bv_val, 0, 0);	if(!be_isroot(op)) {		op->o_bd->bd_info = (BackendInfo *) on->on_info;		send_ldap_error(op, rs, LDAP_INSUFFICIENT_ACCESS,			"user modification of overlay database not permitted");		return(rs->sr_err);	}	if(!ov->config->glue) glue_parent(op);	return(SLAP_CB_CONTINUE);}/*** translucent_modrdn()**	if not bound as root, send ACCESS error;**	if !config.glue, glue_parent();**	else return CONTINUE;***/static int translucent_modrdn(Operation *op, SlapReply *rs) {	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;	overlay_stack *ov = on->on_bi.bi_private;	Debug(LDAP_DEBUG_TRACE, "==> translucent_modrdn: %s -> %s\n",		op->o_req_dn.bv_val, op->orr_newrdn.bv_val, 0);	if(!be_isroot(op)) {		op->o_bd->bd_info = (BackendInfo *) on->on_info;		send_ldap_error(op, rs, LDAP_INSUFFICIENT_ACCESS,			"user modification of overlay database not permitted");		return(rs->sr_err);	}	if(!ov->config->glue) glue_parent(op);	return(SLAP_CB_CONTINUE);}/*** translucent_delete()**	if not bound as root, send ACCESS error;**	else return CONTINUE;***/static int translucent_delete(Operation *op, SlapReply *rs) {	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;	Debug(LDAP_DEBUG_TRACE, "==> translucent_delete: %s\n",		op->o_req_dn.bv_val, 0, 0);	if(!be_isroot(op)) {		op->o_bd->bd_info = (BackendInfo *) on->on_info;		send_ldap_error(op, rs, LDAP_INSUFFICIENT_ACCESS,			"user modification of overlay database not permitted");		return(rs->sr_err);	}	return(SLAP_CB_CONTINUE);}static inttranslucent_tag_cb( Operation *op, SlapReply *rs ){	op->o_tag = LDAP_REQ_MODIFY;	op->orm_modlist = op->o_callback->sc_private;	rs->sr_tag = slap_req2res( op->o_tag );	return SLAP_CB_CONTINUE;}/*** translucent_modify()**	modify in local backend if exists in both;**	otherwise, add to local backend;**	fail if not defined in captive backend;***/static int translucent_modify(Operation *op, SlapReply *rs) {	SlapReply nrs = { REP_RESULT };	Operation nop = *op;	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;	overlay_stack *ov = on->on_bi.bi_private;	void *private = op->o_bd->be_private;	Entry ne, *e = NULL, *re = NULL;	Attribute *a, *ax;	Modifications *m, **mm;	int del, rc, erc = 0;	slap_callback cb = { 0 };	Debug(LDAP_DEBUG_TRACE, "==> translucent_modify: %s\n",		op->o_req_dn.bv_val, 0, 0);/*** fetch entry from the captive backend;** if it did not exist, fail;** release it, if captive backend supports this;***/	op->o_bd->bd_info = (BackendInfo *) on->on_info;	op->o_bd->be_private = ov->private;	rc = ov->info->bi_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &re);	op->o_bd->be_private = private;	/* if(ov->config->no_add && (!re || rc != LDAP_SUCCESS)) */	if(rc != LDAP_SUCCESS || re == NULL ) {		send_ldap_error(op, rs, LDAP_NO_SUCH_OBJECT,			"attempt to modify nonexistent local record");		return(rs->sr_err);	}/*** fetch entry from local backend;** if it exists:**	foreach Modification:**	    if attr not present in local:**		if Mod == LDAP_MOD_DELETE:**		    if remote attr not present, return NO_SUCH;**		    if remote attr present, drop this Mod;**		else force this Mod to LDAP_MOD_ADD;**	return CONTINUE;***/	rc = be_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &e);	if(e && rc == LDAP_SUCCESS) {		Debug(LDAP_DEBUG_TRACE, "=> translucent_modify: found local entry\n", 0, 0, 0);		for(mm = &op->orm_modlist; *mm; ) {			m = *mm;			for(a = e->e_attrs; a; a = a->a_next)				if(a->a_desc == m->sml_desc) break;			if(a) {				mm = &m->sml_next;				continue;		/* found local attr */			}			if(m->sml_op == LDAP_MOD_DELETE) {				for(a = re->e_attrs; a; a = a->a_next)					if(a->a_desc == m->sml_desc) break;				/* not found remote attr */				if(!a) {					erc = LDAP_NO_SUCH_ATTRIBUTE;					goto release;				}				if(ov->config->strict) {					erc = LDAP_CONSTRAINT_VIOLATION;					goto release;				}				Debug(LDAP_DEBUG_TRACE,					"=> translucent_modify: silently dropping delete: %s\n",					m->sml_desc->ad_cname.bv_val, 0, 0);				*mm = m->sml_next;				m->sml_next = NULL;				slap_mods_free(m, 1);				continue;			}			m->sml_op = LDAP_MOD_ADD;			mm = &m->sml_next;		}		erc = SLAP_CB_CONTINUE;release:		if(re) {			op->o_bd->be_private = ov->private;			if(ov->info->bi_entry_release_rw)				ov->info->bi_entry_release_rw(op, re, 0);			else				entry_free(re);			op->o_bd->be_private = private;		}		be_entry_release_r(op, e);		if(erc == SLAP_CB_CONTINUE) {			op->o_bd->bd_info = (BackendInfo *) on;			return(erc);		} else if(erc) {			send_ldap_error(op, rs, erc,				"attempt to delete nonexistent attribute");			return(erc);		}	}	/* don't leak remote entry copy */	if(re) {		op->o_bd->be_private = ov->private;		if(ov->info->bi_entry_release_rw)			ov->info->bi_entry_release_rw(op, re, 0);		else			entry_free(re);		op->o_bd->be_private = private;	}/*** foreach Modification:**	if MOD_ADD or MOD_REPLACE, add Attribute;** if no Modifications were suitable:**	if config.strict, throw CONSTRAINT_VIOLATION;**	else, return early SUCCESS;** fabricate Entry with new Attribute chain;** glue_parent() for this Entry;** call bi_op_add() in local backend;***/	Debug(LDAP_DEBUG_TRACE, "=> translucent_modify: fabricating local add\n", 0, 0, 0);	a = NULL;	for(del = 0, ax = NULL, m = op->orm_modlist; m; m = m->sml_next) {		if(((m->sml_op & LDAP_MOD_OP) != LDAP_MOD_ADD) &&		   ((m->sml_op & LDAP_MOD_OP) != LDAP_MOD_REPLACE)) {			Debug(LDAP_DEBUG_ANY,				"=> translucent_modify: silently dropped modification(%d): %s\n",				m->sml_op, m->sml_desc->ad_cname.bv_val, 0);			if((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) del++;			continue;		}		a = ch_calloc(1, sizeof(Attribute));		a->a_desc  = m->sml_desc;		a->a_vals  = m->sml_values;		a->a_nvals = m->sml_nvalues ? m->sml_nvalues : a->a_vals;		a->a_next  = ax;		ax = a;	}	if(del && ov->config->strict) {		free_attr_chain(a);		send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION,			"attempt to delete attributes from local database");		return(rs->sr_err);	}	if(!ax) {		if(ov->config->strict) {			send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION,				"modification contained other than ADD or REPLACE");			return(rs->sr_err);		}		op->o_bd->bd_info = (BackendInfo *) on;		/* rs->sr_text = "no valid modification found"; */		rs->sr_err = LDAP_SUCCESS;		send_ldap_result(op, rs);		return(rs->sr_err);	}	ne.e_id		= NOID;	ne.e_name	= op->o_req_dn;	ne.e_nname	= op->o_req_ndn;	ne.e_attrs	= a;	ne.e_ocflags	= 0;	ne.e_bv.bv_len	= 0;	ne.e_bv.bv_val	= NULL;	ne.e_private	= NULL;	nop.o_tag	= LDAP_REQ_ADD;	nop.oq_add.rs_e	= &ne;	op->o_bd->bd_info = (BackendInfo *) on;	glue_parent(&nop);	cb.sc_response = translucent_tag_cb;	cb.sc_private = op->orm_modlist;	cb.sc_next = nop.o_callback;	nop.o_callback = &cb;	rc = on->on_info->oi_orig->bi_op_add(&nop, &nrs);	free_attr_chain(a);	return(rc);}

⌨️ 快捷键说明

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