mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-07 14:18:15 +08:00
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:
parent
4c8efee4a6
commit
364b87f587
9
contrib/slapd-modules/nops/Makefile
Normal file
9
contrib/slapd-modules/nops/Makefile
Normal 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
|
168
contrib/slapd-modules/nops/nops.c
Normal file
168
contrib/slapd-modules/nops/nops.c
Normal 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) */
|
||||
|
32
contrib/slapd-modules/nops/slapo-nops.5
Normal file
32
contrib/slapd-modules/nops/slapo-nops.5
Normal 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
|
Loading…
Reference in New Issue
Block a user