From bbce32ed3cc2d1bf2e5aeaee89d2fe1ef81b71e2 Mon Sep 17 00:00:00 2001
From: "ck@test-centos64.cksoft.de" <ck@test-centos64.cksoft.de>
Date: Tue, 8 Oct 2013 23:14:45 +0200
Subject: [PATCH] ITS#7721 - Allow authTimestamp updates to be forwarded via
 updateref

---
 contrib/slapd-modules/lastbind/lastbind.c     | 46 ++++++++++++++++++-
 .../slapd-modules/lastbind/slapo-lastbind.5   | 11 +++++
 2 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/contrib/slapd-modules/lastbind/lastbind.c b/contrib/slapd-modules/lastbind/lastbind.c
index ae7ede0d57..311be04f77 100644
--- a/contrib/slapd-modules/lastbind/lastbind.c
+++ b/contrib/slapd-modules/lastbind/lastbind.c
@@ -42,6 +42,7 @@
 typedef struct lastbind_info {
 	/* precision to update timestamp in authTimestamp attribute */
 	int timestamp_precision;
+	int forward_updates;	/* use frontend for authTimestamp updates */
 } lastbind_info;
 
 /* Operational attributes */
@@ -74,6 +75,12 @@ static ConfigTable lastbindcfg[] = {
 	  "NAME 'olcLastBindPrecision' "
 	  "DESC 'Precision of authTimestamp attribute' "
 	  "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
+	{ "lastbind_forward_updates", "on|off", 1, 2, 0,
+	  ARG_ON_OFF|ARG_OFFSET,
+	  (void *)offsetof(lastbind_info,forward_updates),
+	  "( OLcfgAt:5.2 NAME 'olcLastBindForwardUpdates' "
+	  "DESC 'Allow authTimestamp updates to be forwarded via updateref' "
+	  "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
 	{ NULL, NULL, 0, 0, 0, ARG_IGNORED }
 };
 
@@ -82,7 +89,7 @@ static ConfigOCs lastbindocs[] = {
 	  "NAME 'olcLastBindConfig' "
 	  "DESC 'Last Bind configuration' "
 	  "SUP olcOverlayConfig "
-	  "MAY ( olcLastBindPrecision ) )",
+	  "MAY ( olcLastBindPrecision $ olcLastBindForwardUpdates) )",
 	  Cft_Overlay, lastbindcfg, NULL, NULL },
 	{ NULL, 0, NULL }
 };
@@ -173,14 +180,49 @@ done:
 		Operation op2 = *op;
 		SlapReply r2 = { REP_RESULT };
 		slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
+		LDAPControl c, *ca[2];
+		lastbind_info *lbi = (lastbind_info *) op->o_callback->sc_private;
 
 		/* This is a DSA-specific opattr, it never gets replicated. */
 		op2.o_tag = LDAP_REQ_MODIFY;
 		op2.o_callback = &cb;
 		op2.orm_modlist = mod;
+		op2.orm_no_opattrs = 0;
 		op2.o_dn = op->o_bd->be_rootdn;
 		op2.o_ndn = op->o_bd->be_rootndn;
-		op2.o_dont_replicate = 1;
+
+		/*
+		 * Code for forwarding of updates adapted from ppolicy.c of slapo-ppolicy
+		 *
+		 * If this server is a shadow and forward_updates is true,
+		 * use the frontend to perform this modify. That will trigger
+		 * the update referral, which can then be forwarded by the
+		 * chain overlay. Obviously the updateref and chain overlay
+		 * must be configured appropriately for this to be useful.
+		 */
+		if ( SLAP_SHADOW( op->o_bd ) && lbi->forward_updates ) {
+			op2.o_bd = frontendDB;
+
+			/* Must use Relax control since these are no-user-mod */
+			op2.o_relax = SLAP_CONTROL_CRITICAL;
+			op2.o_ctrls = ca;
+			ca[0] = &c;
+			ca[1] = NULL;
+			BER_BVZERO( &c.ldctl_value );
+			c.ldctl_iscritical = 1;
+			c.ldctl_oid = LDAP_CONTROL_RELAX;
+		} else {
+			/* If not forwarding, don't update opattrs and don't replicate */
+			if ( SLAP_SINGLE_SHADOW( op->o_bd )) {
+				op2.orm_no_opattrs = 1;
+				op2.o_dont_replicate = 1;
+			}
+			/* TODO: not sure what this does in slapo-ppolicy */
+			/*
+			op2.o_bd->bd_info = (BackendInfo *)on->on_info;
+			*/
+		}
+
 		rc = op->o_bd->be_modify( &op2, &r2 );
 		slap_mods_free( mod, 1 );
 	}
diff --git a/contrib/slapd-modules/lastbind/slapo-lastbind.5 b/contrib/slapd-modules/lastbind/slapo-lastbind.5
index 652528278b..d92a95da8d 100644
--- a/contrib/slapd-modules/lastbind/slapo-lastbind.5
+++ b/contrib/slapd-modules/lastbind/slapo-lastbind.5
@@ -56,6 +56,17 @@ old, it will not be changed.
 If this configuration option is omitted, the
 .B authTimestamp
 attribute is updated on each successful bind operation.
+.TP
+.B lastbind_forward_updates
+Specify that updates of the authTimestamp attribute
+on a consumer should be forwarded
+to a master instead of being written directly into the consumer's local
+database. This setting is only useful on a replication consumer, and
+also requires the
+.B updateref
+setting and
+.B chain
+overlay to be appropriately configured.
 
 .SH EXAMPLE
 This example configures the
-- 
GitLab