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

📄 refint.c

📁 ldap服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* refint.c - referential integrity module *//* $OpenLDAP: pkg/ldap/servers/slapd/overlays/refint.c,v 1.7.2.11 2007/01/02 21:44:08 kurt Exp $ *//* This work is part of OpenLDAP Software <http://www.openldap.org/>. * * Copyright 2004-2007 The OpenLDAP Foundation. * Portions Copyright 2004 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"/* This module maintains referential integrity for a set of * DN-valued attributes by searching for all references to a given * DN whenever the DN is changed or its entry is deleted, and making * the appropriate update. * * Updates are performed using the database rootdn, but the ModifiersName * is always set to refint_dn. */#ifdef SLAPD_OVER_REFINT#include <stdio.h>#include <ac/string.h>#include <ac/socket.h>#include "slap.h"static slap_overinst refint;/* The DN to use in the ModifiersName for all refint updates */static BerValue refint_dn = BER_BVC("cn=Referential Integrity Overlay");typedef struct refint_attrs_s {	struct refint_attrs_s *next;	AttributeDescription *attr;} refint_attrs;typedef struct dependents_s {	struct dependents_s *next;	BerValue dn;				/* target dn */	Modifications *mm;} dependent_data;typedef struct refint_data_s {	const char *message;			/* breadcrumbs */	struct refint_attrs_s *attrs;	/* list of known attrs */	struct dependents_s *mods;		/* modifications returned from callback */	BerValue dn;				/* basedn in parent, searchdn in call */	BerValue newdn;				/* replacement value for modrdn callback */	BerValue nnewdn;			/* normalized replacement value */	BerValue nothing;			/* the nothing value, if needed */	BerValue nnothing;			/* normalized nothingness */} refint_data;/*** allocate new refint_data;** initialize, copy basedn;** store in on_bi.bi_private;***/static intrefint_db_init(	BackendDB	*be){	slap_overinst *on = (slap_overinst *)be->bd_info;	refint_data *id = ch_malloc(sizeof(refint_data));	id->message = "_init";	id->attrs = NULL;	id->newdn.bv_val = NULL;	id->nothing.bv_val = NULL;	id->nnothing.bv_val = NULL;	ber_dupbv( &id->dn, &be->be_nsuffix[0] );	on->on_bi.bi_private = id;	return(0);}/*** if command = attributes:**	foreach argument:**		convert to attribute;**		add to configured attribute list;** elseif command = basedn:**	set our basedn to argument;***/static intrefint_config(	BackendDB	*be,	const char	*fname,	int		lineno,	int		argc,	char		**argv){	slap_overinst *on	= (slap_overinst *) be->bd_info;	refint_data *id	= on->on_bi.bi_private;	refint_attrs *ip;	const char *text;	AttributeDescription *ad;	BerValue dn;	int i;	if(!strcasecmp(*argv, "refint_attributes")) {		for(i = 1; i < argc; i++) {			for(ip = id->attrs; ip; ip = ip->next)			    if(!strcmp(argv[i], ip->attr->ad_cname.bv_val)) {				Debug(LDAP_DEBUG_ANY,					"%s: line %d: duplicate attribute <s>, ignored\n",					fname, lineno, argv[i]);				continue;			}			ad = NULL;			if(slap_str2ad(argv[i], &ad, &text) != LDAP_SUCCESS) {				Debug(LDAP_DEBUG_ANY,					"%s: line %d: bad attribute <%s>, ignored\n",					fname, lineno, text);				continue;		/* XXX */			} else if(ad->ad_next) {				Debug(LDAP_DEBUG_ANY,					"%s: line %d: multiple attributes match <%s>, ignored\n",					fname, lineno, argv[i]);				continue;			}			ip = ch_malloc(sizeof(refint_attrs));			ip->attr = ad;			ip->next = id->attrs;			id->attrs = ip;			Debug(LDAP_DEBUG_ANY, "%s: line %d: new attribute <%s>\n",				fname, lineno, argv[i]);		}	} else if(!strcasecmp(*argv, "refint_base")) {		/* XXX only one basedn (yet) - need validate argument! */		if(id->dn.bv_val) ch_free(id->dn.bv_val);		ber_str2bv( argv[1], 0, 0, &dn );		Debug(LDAP_DEBUG_ANY, "%s: line %d: new baseDN <%s>\n",			fname, lineno, argv[1]);		if(dnNormalize(0, NULL, NULL, &dn, &id->dn, NULL)) {			Debug(LDAP_DEBUG_ANY, "%s: line %d: bad baseDN!\n", fname, lineno, 0);			return(1);		}	} else if(!strcasecmp(*argv, "refint_nothing")) {		if(id->nothing.bv_val) ch_free(id->nothing.bv_val);		if(id->nnothing.bv_val) ch_free(id->nnothing.bv_val);		ber_str2bv( argv[1], 0, 1, &id->nothing );		if(dnNormalize(0, NULL, NULL, &id->nothing, &id->nnothing, NULL)) {			Debug(LDAP_DEBUG_ANY, "%s: line %d: bad nothingDN!\n", fname, lineno, 0);			return(1);		}		Debug(LDAP_DEBUG_ANY, "%s: line %d: new nothingDN<%s>\n",			fname, lineno, argv[1]);	} else {		return(SLAP_CONF_UNKNOWN);	}	id->message = "_config";	return(0);}/*** nothing really happens here;***/static intrefint_open(	BackendDB *be){	slap_overinst *on	= (slap_overinst *)be->bd_info;	refint_data *id	= on->on_bi.bi_private;	id->message		= "_open";	return(0);}/*** foreach configured attribute:**	free it;** free our basedn;** (do not) free id->message;** reset on_bi.bi_private;** free our config data;***/static intrefint_close(	BackendDB *be){	slap_overinst *on	= (slap_overinst *) be->bd_info;	refint_data *id	= on->on_bi.bi_private;	refint_attrs *ii, *ij;	id->message		= "_close";	for(ii = id->attrs; ii; ii = ij) {		ij = ii->next;		ch_free(ii);	}	ch_free(id->dn.bv_val);	ch_free(id->nothing.bv_val);	ch_free(id->nnothing.bv_val);	on->on_bi.bi_private = NULL;	/* XXX */	ch_free(id);	return(0);}/*** delete callback** generates a list of Modification* from search results*/static intrefint_delete_cb(	Operation *op,	SlapReply *rs){	Attribute *a;	BerVarray b = NULL;	refint_data *dd = op->o_callback->sc_private;	refint_attrs *ia, *da = dd->attrs;	dependent_data *ip;	Modifications *mp, *ma;	int i;	Debug(LDAP_DEBUG_TRACE, "refint_delete_cb <%s>\n",		rs->sr_entry ? rs->sr_entry->e_name.bv_val : "NOTHING", 0, 0);	if (rs->sr_type != REP_SEARCH || !rs->sr_entry) return(0);	dd->message = "_delete_cb";	/*	** foreach configured attribute type:	**	if this attr exists in the search result,	**	and it has a value matching the target:	**		allocate a Modification;	**		allocate its array of 2 BerValues;	**		if only one value, and we have a configured Nothing:	**			allocate additional Modification	**			type = MOD_ADD	**			BerValues[] = { Nothing, NULL };	**			add to list	**		type = MOD_DELETE	**		BerValues[] = { our target dn, NULL };	**	add this mod to the list of mods;	**	*/	ip = ch_malloc(sizeof(dependent_data));	ip->dn.bv_val = NULL;	ip->next = NULL;	ip->mm = NULL;	ma = NULL;	for(ia = da; ia; ia = ia->next) {	    if ( (a = attr_find(rs->sr_entry->e_attrs, ia->attr) ) )		for(i = 0, b = a->a_nvals; b[i].bv_val; i++)		    if(bvmatch(&dd->dn, &b[i])) {			if(!ip->dn.bv_val) ber_dupbv(&ip->dn, &rs->sr_entry->e_nname);			if(!b[1].bv_val && dd->nothing.bv_val) {				mp = ch_malloc(sizeof(Modifications));				mp->sml_desc = ia->attr;		/* XXX */				mp->sml_type = a->a_desc->ad_cname;				mp->sml_values  = ch_malloc(2 * sizeof(BerValue));				mp->sml_nvalues = ch_malloc(2 * sizeof(BerValue));				mp->sml_values[1].bv_len = mp->sml_nvalues[1].bv_len = 0;				mp->sml_values[1].bv_val = mp->sml_nvalues[1].bv_val = NULL;				mp->sml_op = LDAP_MOD_ADD;				mp->sml_flags = 0;				ber_dupbv(&mp->sml_values[0],  &dd->nothing);				ber_dupbv(&mp->sml_nvalues[0], &dd->nnothing);				mp->sml_next = ma;				ma = mp;			}		 	/* this might violate the object class */			mp = ch_malloc(sizeof(Modifications));			mp->sml_desc = ia->attr;		/* XXX */			mp->sml_type = a->a_desc->ad_cname;			mp->sml_values  = ch_malloc(2 * sizeof(BerValue));			mp->sml_nvalues = ch_malloc(2 * sizeof(BerValue));			mp->sml_values[1].bv_len = mp->sml_nvalues[1].bv_len = 0;			mp->sml_values[1].bv_val = mp->sml_nvalues[1].bv_val = NULL;			mp->sml_op = LDAP_MOD_DELETE;			mp->sml_flags = 0;			ber_dupbv(&mp->sml_values[0], &dd->dn);			ber_dupbv(&mp->sml_nvalues[0], &mp->sml_values[0]);			mp->sml_next = ma;			ma = mp;			Debug(LDAP_DEBUG_TRACE, "refint_delete_cb: %s: %s\n",				a->a_desc->ad_cname.bv_val, dd->dn.bv_val, 0);			break;	    }	}	ip->mm = ma;	ip->next = dd->mods;	dd->mods = ip;	return(0);}/*** null callback** does nothing*/static intrefint_null_cb(	Operation *op,	SlapReply *rs){	((refint_data *)op->o_callback->sc_private)->message = "_null_cb";	return(LDAP_SUCCESS);}/*** modrdn callback** generates a list of Modification* from search results*/

⌨️ 快捷键说明

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