Here is slapo-nops, used to remove idempotent operations (i.e.: replacing

an attribute values by the exact same values)
This commit is contained in:
Emmanuel Dreyfus 2008-05-19 22:44:08 +00:00
parent 4c8efee4a6
commit 364b87f587
3 changed files with 209 additions and 0 deletions

View File

@ -0,0 +1,9 @@
CPPFLAGS+=-I../../../include -I../../../servers/slapd
all: nops.so
nops.so: nops.c
$(CC) -shared $(CPPFLAGS) -Wall -o $@ $?
clean:
rm nops.so

View File

@ -0,0 +1,168 @@
/* $OpenLDAP$ */
/* nops.c - Overlay to filter idempotent operations */
/*
* Copyright 2008 Emmanuel Dreyfus
* 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_NOPS
#include <stdio.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "lutil.h"
#include "slap.h"
#include "config.h"
static ConfigDriver nops_cf_gen;
static int nops_cf_gen( ConfigArgs *c ) { return 0; }
static void
nops_rm_mod( Modifications **mods, Modifications *mod ) {
Modifications *next, *m;
next = mod->sml_next;
if (*mods == mod) {
*mods = next;
} else {
Modifications *m;
for (m = *mods; m; m = m->sml_next) {
if (m->sml_next == mod) {
m->sml_next = next;
break;
}
}
}
for (m = *mods; m; m = m->sml_next)
mod->sml_next = NULL;
slap_mods_free(mod, 1);
return;
}
static int
nops_modify( Operation *op, SlapReply *rs )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
Backend *be = op->o_bd;
Entry *target_entry = NULL;
Modifications *m;
int rc;
if ((m = op->orm_modlist) == NULL) {
op->o_bd->bd_info = (BackendInfo *)(on->on_info);
send_ldap_error(op, rs, LDAP_INVALID_SYNTAX,
"nops() got null orm_modlist");
return(rs->sr_err);
}
op->o_bd = on->on_info->oi_origdb;
rc = be_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &target_entry);
op->o_bd = be;
if (rc != 0 || target_entry == NULL)
return 0;
/*
* For each attribute modification, check if the
* modification and the old entry are the same.
*/
while (m) {
int i, j;
int found;
Attribute *a;
BerVarray bm;
BerVarray bt;
Modifications *mc;
mc = m;
m = m->sml_next;
/* Check only replace sub-operations */
if ((mc->sml_op & LDAP_MOD_OP) != LDAP_MOD_REPLACE)
continue;
/* If there is no values, skip */
if (((bm = mc->sml_values ) == NULL ) || (bm[0].bv_val == NULL))
continue;
/* If the attribute does not exist in old entry, skip */
if ((a = attr_find(target_entry->e_attrs, mc->sml_desc)) == NULL)
continue;
if ((bt = a->a_vals) == NULL)
continue;
/* For each value replaced, do we find it in old entry? */
found = 0;
for (i = 0; bm[i].bv_val; i++) {
for (j = 0; bt[j].bv_val; j++) {
if (bm[i].bv_len != bt[j].bv_len)
continue;
if (memcmp(bm[i].bv_val, bt[j].bv_val, bt[j].bv_len) != 0)
continue;
found++;
break;
}
}
/* Did we find as many values as we had in old entry? */
if (i != a->a_numvals || found != a->a_numvals)
continue;
/* This is a nop, remove it */
Debug(LDAP_DEBUG_TRACE, "removing nop on %s%s%s",
a->a_desc->ad_cname.bv_val, "", "");
nops_rm_mod(&op->orm_modlist, mc);
}
if (target_entry) {
op->o_bd = on->on_info->oi_origdb;
be_entry_release_r(op, target_entry);
op->o_bd = be;
}
if ((m = op->orm_modlist) == NULL) {
op->o_bd->bd_info = (BackendInfo *)(on->on_info);
send_ldap_error(op, rs, LDAP_SUCCESS, "");
return(rs->sr_err);
return (rs->sr_err);
}
return SLAP_CB_CONTINUE;
}
static slap_overinst nops_ovl;
#if SLAPD_OVER_NOPS == SLAPD_MOD_DYNAMIC
static
#endif
int
nops_initialize( void ) {
nops_ovl.on_bi.bi_type = "nops";
nops_ovl.on_bi.bi_op_modify = nops_modify;
return overlay_register( &nops_ovl );
}
#if SLAPD_OVER_NOPS == SLAPD_MOD_DYNAMIC
int init_module(int argc, char *argv[]) {
return nops_initialize();
}
#endif
#endif /* defined(SLAPD_OVER_NOPS) */

View File

@ -0,0 +1,32 @@
.TH SLAPO-NOPS 5 "RELEASEDATE" "OpenLDAP LDVERSION"
.\" Copyright 2008 Emmanuel Dreyfus
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.\" $OpenLDAP$
.SH NAME
slapo-nops \- Remove Null Operations Overlay to slapd
.SH SYNOPSIS
ETCDIR/slapd.conf
.SH DESCRIPTION
Some broken client tend to implement modifications as replace operations
where all attributes are replaced, most of the time by the same values
they had before. This can cause undesirable load on logs, ACL evaluation,
or replication trafic.
This overlay detects idempotent replace operations and filter them out.
.SH CONFIGURATION
This overlay had no specific configuration.
.SH EXAMPLES
.LP
.RS
.nf
overlay nops
.RE
.SH FILES
.TP
ETCDIR/slapd.conf
default slapd configuration file
.SH SEE ALSO
.BR slapd.conf (5).
.SH ACKNOWLEDGEMENTS
This module was written in 2008 by Emmanuel Dreyfus.
.so ../Project