]> git.sur5r.net Git - openldap/blobdiff - contrib/slapd-modules/lastbind/lastbind.c
ITS#7721 - Allow authTimestamp updates to be forwarded via updateref
[openldap] / contrib / slapd-modules / lastbind / lastbind.c
index 9a38a454d7f23d249e23120e1323882bbfb00dee..311be04f771f564d87228581149234623b687096 100644 (file)
@@ -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 */
@@ -70,19 +71,25 @@ static ConfigTable lastbindcfg[] = {
        { "lastbind-precision", "seconds", 2, 2, 0,
          ARG_INT|ARG_OFFSET,
          (void *)offsetof(lastbind_info, timestamp_precision),
-         "( OLcfgAt:5.1 "
+         "( OLcfgCtAt:5.1 "
          "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 }
 };
 
 static ConfigOCs lastbindocs[] = {
-       { "( OLcfgOc:5.1 "
+       { "( OLcfgCtOc:5.1 "
          "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 );
        }