summaryrefslogtreecommitdiffstats
path: root/contrib/slapd-modules/nops
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:23:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:23:53 +0000
commitc000cad09d0b54c455c99271bfb996c2dfe13073 (patch)
treee47ca809ed512d7fb43ec3d555753b1b658e9819 /contrib/slapd-modules/nops
parentInitial commit. (diff)
downloadopenldap-c000cad09d0b54c455c99271bfb996c2dfe13073.tar.xz
openldap-c000cad09d0b54c455c99271bfb996c2dfe13073.zip
Adding upstream version 2.4.47+dfsg.upstream/2.4.47+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--contrib/slapd-modules/nops/Makefile46
-rw-r--r--contrib/slapd-modules/nops/nops.c177
-rw-r--r--contrib/slapd-modules/nops/slapo-nops.532
3 files changed, 255 insertions, 0 deletions
diff --git a/contrib/slapd-modules/nops/Makefile b/contrib/slapd-modules/nops/Makefile
new file mode 100644
index 0000000..eda7b47
--- /dev/null
+++ b/contrib/slapd-modules/nops/Makefile
@@ -0,0 +1,46 @@
+# $OpenLDAP$
+
+LDAP_SRC = ../../..
+LDAP_BUILD = $(LDAP_SRC)
+LDAP_INC = -I$(LDAP_BUILD)/include -I$(LDAP_SRC)/include -I$(LDAP_SRC)/servers/slapd
+LDAP_LIB = $(LDAP_BUILD)/libraries/libldap_r/libldap_r.la \
+ $(LDAP_BUILD)/libraries/liblber/liblber.la
+
+LIBTOOL = $(LDAP_BUILD)/libtool
+CC = gcc
+OPT = -g -O2 -Wall
+DEFS = -DSLAPD_OVER_NOPS=SLAPD_MOD_DYNAMIC
+INCS = $(LDAP_INC)
+LIBS = $(LDAP_LIB)
+
+PROGRAMS = nops.la
+LTVER = 0:0:0
+
+prefix=/usr/local
+exec_prefix=$(prefix)
+ldap_subdir=/openldap
+
+libdir=$(exec_prefix)/lib
+libexecdir=$(exec_prefix)/libexec
+moduledir = $(libexecdir)$(ldap_subdir)
+
+.SUFFIXES: .c .o .lo
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(CC) $(OPT) $(DEFS) $(INCS) -c $<
+
+all: $(PROGRAMS)
+
+nops.la: nops.lo
+ $(LIBTOOL) --mode=link $(CC) $(OPT) -version-info $(LTVER) \
+ -rpath $(moduledir) -module -o $@ $? $(LIBS)
+
+clean:
+ rm -rf *.o *.lo *.la .libs
+
+install: $(PROGRAMS)
+ mkdir -p $(DESTDIR)$(moduledir)
+ for p in $(PROGRAMS) ; do \
+ $(LIBTOOL) --mode=install cp $$p $(DESTDIR)$(moduledir) ; \
+ done
+
diff --git a/contrib/slapd-modules/nops/nops.c b/contrib/slapd-modules/nops/nops.c
new file mode 100644
index 0000000..4e8549e
--- /dev/null
+++ b/contrib/slapd-modules/nops/nops.c
@@ -0,0 +1,177 @@
+/* nops.c - Overlay to filter idempotent operations */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2008-2018 The OpenLDAP Foundation.
+ * 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>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was originally developed by the Emmanuel Dreyfus for
+ * inclusion in OpenLDAP Software.
+ */
+#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;
+ }
+ }
+ }
+
+ 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) {
+ slap_callback *cb = op->o_callback;
+
+ op->o_bd->bd_info = (BackendInfo *)(on->on_info);
+ op->o_callback = NULL;
+ send_ldap_error(op, rs, LDAP_SUCCESS, "");
+ op->o_callback = cb;
+
+ 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) */
+
diff --git a/contrib/slapd-modules/nops/slapo-nops.5 b/contrib/slapd-modules/nops/slapo-nops.5
new file mode 100644
index 0000000..ac8f19d
--- /dev/null
+++ b/contrib/slapd-modules/nops/slapo-nops.5
@@ -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