]> git.sur5r.net Git - openldap/commitdiff
add support for session tracking (draft-wahl-ldap-sessio) to proxy backends requests
authorPierangelo Masarati <ando@openldap.org>
Wed, 22 Aug 2007 15:49:35 +0000 (15:49 +0000)
committerPierangelo Masarati <ando@openldap.org>
Wed, 22 Aug 2007 15:49:35 +0000 (15:49 +0000)
26 files changed:
doc/man/man5/slapd-ldap.5
doc/man/man5/slapd-meta.5
servers/slapd/back-ldap/add.c
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/compare.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/delete.c
servers/slapd/back-ldap/extended.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/modrdn.c
servers/slapd/back-ldap/proto-ldap.h
servers/slapd/back-ldap/search.c
servers/slapd/back-meta/add.c
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/bind.c
servers/slapd/back-meta/compare.c
servers/slapd/back-meta/config.c
servers/slapd/back-meta/delete.c
servers/slapd/back-meta/modify.c
servers/slapd/back-meta/modrdn.c
servers/slapd/back-meta/search.c
servers/slapd/controls.c
servers/slapd/daemon.c
servers/slapd/proto-slap.h
servers/slapd/slap.h

index 847ea6d6570d4a2976eb8ef64fa0f44d4e1063b6..ee9fbffdd496971b732d4f797ffcedd442426fa3 100644 (file)
@@ -429,6 +429,13 @@ or when chasing a referral, if
 is set to
 .IR yes .
 
+.TP
+.B session\-tracking\-request {NO|yes}
+Adds session tracking control for all requests.
+The client's IP and hostname, and the identity associated to each request,
+if known, are sent to the remote server for informational purposes.
+This directive is incompatible with setting \fIprotocol\-version\fP to 2.
+
 .TP
 .B single\-conn {NO|yes}
 Discards current cached connection when the client rebinds.
index 5816c0f753ab2f61d48ff9acfd07d84c8e0c80d1..e2c5bbe0e259ed1ecf6e7f7bb6f6c3c75cdf6020 100644 (file)
@@ -172,6 +172,15 @@ or when chasing a referral, if
 is set to
 .IR yes .
 
+.TP
+.B session\-tracking\-request {NO|yes}
+Adds session tracking control for all requests.
+The client's IP and hostname, and the identity associated to each request,
+if known, are sent to the remote server for informational purposes.
+This directive is incompatible with setting \fIprotocol\-version\fP to 2.
+If set before any target specification, it affects all targets, unless
+overridden by any per-target directive.
+
 .TP
 .B single\-conn {NO|yes}
 Discards current cached connection when the client rebinds.
index 9a5c4f5422a3acdf0a3f3b524bf328e484e1d264..8398162ee45f795b1a57e08acac1a9bc5d6c110b 100644 (file)
@@ -93,8 +93,7 @@ ldap_back_add(
 
 retry:
        ctrls = op->o_ctrls;
-       rs->sr_err = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-               li->li_version, &li->li_idassert, op, rs, &ctrls );
+       rs->sr_err = ldap_back_controls_add( op, rs, lc, &ctrls );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
                goto cleanup;
@@ -109,13 +108,13 @@ retry:
                retrying &= ~LDAP_BACK_RETRYING;
                if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        if ( attrs ) {
                for ( --i; i >= 0; --i ) {
index 442869861d3eab48719c871f845b5ebfe3fe5b45..374a959c7417615859cf555b743aa641c90b50f9 100644 (file)
@@ -310,6 +310,11 @@ typedef struct ldapinfo_t {
 
 #define        LDAP_BACK_F_QUARANTINE          (0x00010000U)
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+#define        LDAP_BACK_F_ST_REQUEST          (0x00020000U)
+#define        LDAP_BACK_F_ST_RESPONSE         (0x00040000U)
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
 #define        LDAP_BACK_ISSET_F(ff,f)         ( ( (ff) & (f) ) == (f) )
 #define        LDAP_BACK_ISMASK_F(ff,m,f)      ( ( (ff) & (m) ) == (f) )
 
@@ -343,6 +348,11 @@ typedef struct ldapinfo_t {
 
 #define        LDAP_BACK_QUARANTINE(li)        LDAP_BACK_ISSET( (li), LDAP_BACK_F_QUARANTINE )
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+#define        LDAP_BACK_ST_REQUEST(li)        LDAP_BACK_ISSET( (li), LDAP_BACK_F_ST_REQUEST)
+#define        LDAP_BACK_ST_RESPONSE(li)       LDAP_BACK_ISSET( (li), LDAP_BACK_F_ST_RESPONSE)
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
        int                     li_version;
 
        /* cached connections; 
index fd5e39b217bfcdf7c8ec65a041354b585c03fe78..d27d958fd675e44151b43af7d027283e609a6e7e 100644 (file)
@@ -173,7 +173,10 @@ ldap_back_bind( Operation *op, SlapReply *rs )
        ldapinfo_t              *li = (ldapinfo_t *) op->o_bd->be_private;
        ldapconn_t              *lc;
 
-       int                     rc = 0;
+       LDAPControl             **ctrls = NULL;
+       struct berval           save_o_dn;
+       int                     save_o_do_not_cache,
+                               rc = 0;
        ber_int_t               msgid;
        ldap_back_send_t        retrying = LDAP_BACK_RETRYING;
 
@@ -205,11 +208,27 @@ ldap_back_bind( Operation *op, SlapReply *rs )
        }
        LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
 
+       /* don't add proxyAuthz; set the bindDN */
+       save_o_dn = op->o_dn;
+       save_o_do_not_cache = op->o_do_not_cache;
+       op->o_dn = op->o_req_dn;
+       op->o_do_not_cache = 1;
+
+       ctrls = op->o_ctrls;
+       rc = ldap_back_controls_add( op, rs, lc, &ctrls );
+       op->o_dn = save_o_dn;
+       op->o_do_not_cache = save_o_do_not_cache;
+       if ( rc != LDAP_SUCCESS ) {
+               send_ldap_result( op, rs );
+               ldap_back_release_conn( li, lc );
+               return( rc );
+       }
+
 retry:;
        /* method is always LDAP_AUTH_SIMPLE if we got here */
        rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val,
                        LDAP_SASL_SIMPLE,
-                       &op->orb_cred, op->o_ctrls, NULL, &msgid );
+                       &op->orb_cred, ctrls, NULL, &msgid );
        /* FIXME: should we always retry, or only when piping the bind
         * in the "override" connection pool? */
        rc = ldap_back_op_result( lc, op, rs, msgid,
@@ -222,6 +241,8 @@ retry:;
                }
        }
 
+       ldap_back_controls_free( op, rs, &ctrls );
+
        if ( rc == LDAP_SUCCESS ) {
                /* If defined, proxyAuthz will be used also when
                 * back-ldap is the authorizing backend; for this
@@ -2210,38 +2231,19 @@ done:;
  */
 int
 ldap_back_proxy_authz_ctrl(
+               Operation       *op,
+               SlapReply       *rs,
                struct berval   *bound_ndn,
                int             version,
                slap_idassert_t *si,
-               Operation       *op,
-               SlapReply       *rs,
-               LDAPControl     ***pctrls )
+               LDAPControl     *ctrl )
 {
-       LDAPControl             **ctrls = NULL;
-       int                     i = 0;
        slap_idassert_mode_t    mode;
        struct berval           assertedID,
                                ndn;
        int                     isroot = 0;
 
-       *pctrls = NULL;
-
-       rs->sr_err = LDAP_SUCCESS;
-
-       /* don't proxyAuthz if protocol is not LDAPv3 */
-       switch ( version ) {
-       case LDAP_VERSION3:
-               break;
-
-       case 0:
-               if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
-                       break;
-               }
-               /* fall thru */
-
-       default:
-               goto done;
-       }
+       rs->sr_err = SLAP_CB_CONTINUE;
 
        /* FIXME: SASL/EXTERNAL over ldapi:// doesn't honor the authcID,
         * but if it is not set this test fails.  We need a different
@@ -2391,32 +2393,20 @@ ldap_back_proxy_authz_ctrl(
                goto done;
        }
 
-       if ( op->o_ctrls ) {
-               for ( i = 0; op->o_ctrls[ i ]; i++ )
-                       /* just count ctrls */ ;
-       }
-
-       ctrls = op->o_tmpalloc( sizeof( LDAPControl * ) * (i + 2) + sizeof( LDAPControl ),
-                       op->o_tmpmemctx );
-       ctrls[ 0 ] = (LDAPControl *)&ctrls[ i + 2 ];
-       
-       ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
-       ctrls[ 0 ]->ldctl_iscritical = 1;
-
        switch ( si->si_mode ) {
        /* already in u:ID or dn:DN form */
        case LDAP_BACK_IDASSERT_OTHERID:
        case LDAP_BACK_IDASSERT_OTHERDN:
-               ber_dupbv_x( &ctrls[ 0 ]->ldctl_value, &assertedID, op->o_tmpmemctx );
+               ber_dupbv_x( &ctrl->ldctl_value, &assertedID, op->o_tmpmemctx );
                break;
 
        /* needs the dn: prefix */
        default:
-               ctrls[ 0 ]->ldctl_value.bv_len = assertedID.bv_len + STRLENOF( "dn:" );
-               ctrls[ 0 ]->ldctl_value.bv_val = op->o_tmpalloc( ctrls[ 0 ]->ldctl_value.bv_len + 1,
+               ctrl->ldctl_value.bv_len = assertedID.bv_len + STRLENOF( "dn:" );
+               ctrl->ldctl_value.bv_val = op->o_tmpalloc( ctrl->ldctl_value.bv_len + 1,
                                op->o_tmpmemctx );
-               AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val, "dn:", STRLENOF( "dn:" ) );
-               AC_MEMCPY( &ctrls[ 0 ]->ldctl_value.bv_val[ STRLENOF( "dn:" ) ],
+               AC_MEMCPY( ctrl->ldctl_value.bv_val, "dn:", STRLENOF( "dn:" ) );
+               AC_MEMCPY( &ctrl->ldctl_value.bv_val[ STRLENOF( "dn:" ) ],
                                assertedID.bv_val, assertedID.bv_len + 1 );
                break;
        }
@@ -2426,7 +2416,7 @@ ldap_back_proxy_authz_ctrl(
         * this hack provides compatibility with those DSAs that
         * implement it this way */
        if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) {
-               struct berval           authzID = ctrls[ 0 ]->ldctl_value;
+               struct berval           authzID = ctrl->ldctl_value;
                BerElementBuffer        berbuf;
                BerElement              *ber = (BerElement *)&berbuf;
                ber_tag_t               tag;
@@ -2440,7 +2430,7 @@ ldap_back_proxy_authz_ctrl(
                        goto free_ber;
                }
 
-               if ( ber_flatten2( ber, &ctrls[ 0 ]->ldctl_value, 1 ) == -1 ) {
+               if ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) {
                        rs->sr_err = LDAP_OTHER;
                        goto free_ber;
                }
@@ -2450,22 +2440,17 @@ free_ber:;
                ber_free_buf( ber );
 
                if ( rs->sr_err != LDAP_SUCCESS ) {
-                       op->o_tmpfree( ctrls, op->o_tmpmemctx );
-                       ctrls = NULL;
                        goto done;
                }
 
        } else if ( si->si_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) {
-               struct berval           authzID = ctrls[ 0 ]->ldctl_value,
+               struct berval           authzID = ctrl->ldctl_value,
                                        tmp;
                BerElementBuffer        berbuf;
                BerElement              *ber = (BerElement *)&berbuf;
                ber_tag_t               tag;
 
                if ( strncasecmp( authzID.bv_val, "dn:", STRLENOF( "dn:" ) ) != 0 ) {
-                       op->o_tmpfree( ctrls[ 0 ]->ldctl_value.bv_val, op->o_tmpmemctx );
-                       op->o_tmpfree( ctrls, op->o_tmpmemctx );
-                       ctrls = NULL;
                        rs->sr_err = LDAP_PROTOCOL_ERROR;
                        goto done;
                }
@@ -2485,7 +2470,7 @@ free_ber:;
                        goto free_ber2;
                }
 
-               if ( ber_flatten2( ber, &ctrls[ 0 ]->ldctl_value, 1 ) == -1 ) {
+               if ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 ) {
                        rs->sr_err = LDAP_OTHER;
                        goto free_ber2;
                }
@@ -2495,20 +2480,119 @@ free_ber2:;
                ber_free_buf( ber );
 
                if ( rs->sr_err != LDAP_SUCCESS ) {
-                       op->o_tmpfree( ctrls, op->o_tmpmemctx );
-                       ctrls = NULL;
                        goto done;
                }
 
-               ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ;
+               ctrl->ldctl_oid = LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ;
+       }
+
+done:;
+
+       return rs->sr_err;
+}
+
+/*
+ * Add controls;
+ *
+ * if any needs to be added, it is prepended to existing ones,
+ * in a newly allocated array.  The companion function
+ * ldap_back_controls_free() must be used to restore the original
+ * status of op->o_ctrls.
+ */
+int
+ldap_back_controls_add(
+               Operation       *op,
+               SlapReply       *rs,
+               ldapconn_t      *lc,
+               LDAPControl     ***pctrls )
+{
+       ldapinfo_t      *li = (ldapinfo_t *)op->o_bd->be_private;
+
+       LDAPControl     **ctrls = NULL;
+       /* set to the maximum number of controls this backend can add */
+       LDAPControl     c[ 2 ] = { 0 };
+       int             i = 0, j = 0;
+
+       *pctrls = NULL;
+
+       rs->sr_err = LDAP_SUCCESS;
+
+       /* don't add controls if protocol is not LDAPv3 */
+       switch ( li->li_version ) {
+       case LDAP_VERSION3:
+               break;
+
+       case 0:
+               if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
+                       break;
+               }
+               /* fall thru */
+
+       default:
+               goto done;
+       }
+
+       /* proxyAuthz for identity assertion */
+       switch ( ldap_back_proxy_authz_ctrl( op, rs, &lc->lc_bound_ndn,
+               li->li_version, &li->li_idassert, &c[ j ] ) )
+       {
+       case SLAP_CB_CONTINUE:
+               break;
+
+       case LDAP_SUCCESS:
+               j++;
+               break;
+
+       default:
+               goto done;
+       }
+
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+       /* session tracking */
+       if ( LDAP_BACK_ST_REQUEST( li ) ) {
+               switch ( slap_ctrl_session_tracking_request_add( op, rs, &c[ j ] ) ) {
+               case SLAP_CB_CONTINUE:
+                       break;
+
+               case LDAP_SUCCESS:
+                       j++;
+                       break;
+
+               default:
+                       goto done;
+               }
+       }
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
+       if ( rs->sr_err == SLAP_CB_CONTINUE ) {
+               rs->sr_err = LDAP_SUCCESS;
+       }
+
+       if ( j == 0 ) {
+               goto done;
        }
 
+       if ( op->o_ctrls ) {
+               for ( i = 0; op->o_ctrls[ i ]; i++ )
+                       /* just count ctrls */ ;
+       }
+
+       ctrls = op->o_tmpalloc( sizeof( LDAPControl * ) * (i + j + 1) + j * sizeof( LDAPControl ),
+                       op->o_tmpmemctx );
+       ctrls[ 0 ] = (LDAPControl *)&ctrls[ i + j + 1 ];
+       *ctrls[ 0 ] = c[ 0 ];
+       for ( i = 1; i < j; i++ ) {
+               ctrls[ i ] = &ctrls[ 0 ][ i ];
+               *ctrls[ i ] = c[ i ];
+       }
+
+       i = 0;
        if ( op->o_ctrls ) {
                for ( i = 0; op->o_ctrls[ i ]; i++ ) {
-                       ctrls[ i + 1 ] = op->o_ctrls[ i ];
+                       ctrls[ i + j ] = op->o_ctrls[ i ];
                }
        }
-       ctrls[ i + 1 ] = NULL;
+       ctrls[ i + j ] = NULL;
 
 done:;
        if ( ctrls == NULL ) {
@@ -2521,18 +2605,25 @@ done:;
 }
 
 int
-ldap_back_proxy_authz_ctrl_free( Operation *op, LDAPControl ***pctrls )
+ldap_back_controls_free( Operation *op, SlapReply *rs, LDAPControl ***pctrls )
 {
        LDAPControl     **ctrls = *pctrls;
 
-       /* we assume that the first control is the proxyAuthz
-        * added by back-ldap, so it's the only one we explicitly 
-        * free */
+       /* we assume that the controls added by the proxy come first,
+        * so as soon as we find op->o_ctrls[ 0 ] we can stop */
        if ( ctrls && ctrls != op->o_ctrls ) {
+               int     i;
+
                assert( ctrls[ 0 ] != NULL );
 
-               if ( !BER_BVISNULL( &ctrls[ 0 ]->ldctl_value ) ) {
-                       op->o_tmpfree( ctrls[ 0 ]->ldctl_value.bv_val, op->o_tmpmemctx );
+               for ( i = 0; ctrls[ i ] != NULL; i++ ) {
+                       if ( op->o_ctrls && ctrls[ i ] == op->o_ctrls[ 0 ] ) {
+                               break;
+                       }
+
+                       if ( !BER_BVISNULL( &ctrls[ i ]->ldctl_value ) ) {
+                               op->o_tmpfree( ctrls[ i ]->ldctl_value.bv_val, op->o_tmpmemctx );
+                       }
                }
 
                op->o_tmpfree( ctrls, op->o_tmpmemctx );
index a0a1b598075ffc0c58a399431916519a1169884b..740be2475171d943be20c4eea501305d9e37f815 100644 (file)
@@ -51,8 +51,7 @@ ldap_back_compare(
 
 retry:
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-               li->li_version, &li->li_idassert, op, rs, &ctrls );
+       rc = ldap_back_controls_add( op, rs, lc, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
                goto cleanup;
@@ -69,13 +68,13 @@ retry:
                retrying &= ~LDAP_BACK_RETRYING;
                if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
        
        if ( lc != NULL ) {
                ldap_back_release_conn( li, lc );
index 03acdaab7487130ee3c22500ace868bb6d0b789a..389e17d29ca18ba88a04eaaa8da3aef2b9335a2e 100644 (file)
@@ -69,6 +69,7 @@ enum {
        LDAP_BACK_CFG_CONNPOOLMAX,
        LDAP_BACK_CFG_CANCEL,
        LDAP_BACK_CFG_QUARANTINE,
+       LDAP_BACK_CFG_ST_REQUEST,
        LDAP_BACK_CFG_REWRITE,
 
        LDAP_BACK_CFG_LAST
@@ -183,7 +184,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "X-ORDERED 'VALUES' )",
                NULL, NULL },
-       { "rebind-as-user", "NO|yes", 1, 2, 0,
+       { "rebind-as-user", "true|FALSE", 1, 2, 0,
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_REBIND,
                ldap_back_cf_gen, "( OLcfgDbAt:3.10 "
                        "NAME 'olcDbRebindAsUser' "
@@ -191,7 +192,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsBoolean "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "chase-referrals", "YES|no", 2, 2, 0,
+       { "chase-referrals", "true|FALSE", 2, 2, 0,
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_CHASE,
                ldap_back_cf_gen, "( OLcfgDbAt:3.11 "
                        "NAME 'olcDbChaseReferrals' "
@@ -199,7 +200,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsBoolean "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "t-f-support", "NO|yes|discover", 2, 2, 0,
+       { "t-f-support", "true|FALSE|discover", 2, 2, 0,
                ARG_MAGIC|LDAP_BACK_CFG_T_F,
                ldap_back_cf_gen, "( OLcfgDbAt:3.12 "
                        "NAME 'olcDbTFSupport' "
@@ -207,7 +208,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "proxy-whoami", "NO|yes", 1, 2, 0,
+       { "proxy-whoami", "true|FALSE", 1, 2, 0,
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_WHOAMI,
                ldap_back_cf_gen, "( OLcfgDbAt:3.13 "
                        "NAME 'olcDbProxyWhoAmI' "
@@ -223,7 +224,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "idle-timeout", "timeout", 2, 0, 0,
+       { "idle-timeout", "timeout", 2, 2, 0,
                ARG_MAGIC|LDAP_BACK_CFG_IDLE_TIMEOUT,
                ldap_back_cf_gen, "( OLcfgDbAt:3.15 "
                        "NAME 'olcDbIdleTimeout' "
@@ -231,7 +232,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "conn-ttl", "ttl", 2, 0, 0,
+       { "conn-ttl", "ttl", 2, 2, 0,
                ARG_MAGIC|LDAP_BACK_CFG_CONN_TTL,
                ldap_back_cf_gen, "( OLcfgDbAt:3.16 "
                        "NAME 'olcDbConnTtl' "
@@ -239,7 +240,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "network-timeout", "timeout", 2, 0, 0,
+       { "network-timeout", "timeout", 2, 2, 0,
                ARG_MAGIC|LDAP_BACK_CFG_NETWORK_TIMEOUT,
                ldap_back_cf_gen, "( OLcfgDbAt:3.17 "
                        "NAME 'olcDbNetworkTimeout' "
@@ -247,7 +248,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "protocol-version", "version", 2, 0, 0,
+       { "protocol-version", "version", 2, 2, 0,
                ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_VERSION,
                ldap_back_cf_gen, "( OLcfgDbAt:3.18 "
                        "NAME 'olcDbProtocolVersion' "
@@ -255,7 +256,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsInteger "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "single-conn", "TRUE/FALSE", 2, 0, 0,
+       { "single-conn", "true|FALSE", 2, 2, 0,
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_SINGLECONN,
                ldap_back_cf_gen, "( OLcfgDbAt:3.19 "
                        "NAME 'olcDbSingleConn' "
@@ -263,7 +264,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsBoolean "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "cancel", "ABANDON|ignore|exop", 2, 0, 0,
+       { "cancel", "ABANDON|ignore|exop", 2, 2, 0,
                ARG_MAGIC|LDAP_BACK_CFG_CANCEL,
                ldap_back_cf_gen, "( OLcfgDbAt:3.20 "
                        "NAME 'olcDbCancel' "
@@ -271,7 +272,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "quarantine", "retrylist", 2, 0, 0,
+       { "quarantine", "retrylist", 2, 2, 0,
                ARG_MAGIC|LDAP_BACK_CFG_QUARANTINE,
                ldap_back_cf_gen, "( OLcfgDbAt:3.21 "
                        "NAME 'olcDbQuarantine' "
@@ -279,7 +280,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "use-temporary-conn", "TRUE/FALSE", 2, 0, 0,
+       { "use-temporary-conn", "true|FALSE", 2, 2, 0,
                ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_USETEMP,
                ldap_back_cf_gen, "( OLcfgDbAt:3.22 "
                        "NAME 'olcDbUseTemporaryConn' "
@@ -287,7 +288,7 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsBoolean "
                        "SINGLE-VALUE )",
                NULL, NULL },
-       { "conn-pool-max", "<n>", 2, 0, 0,
+       { "conn-pool-max", "<n>", 2, 2, 0,
                ARG_MAGIC|ARG_INT|LDAP_BACK_CFG_CONNPOOLMAX,
                ldap_back_cf_gen, "( OLcfgDbAt:3.23 "
                        "NAME 'olcDbConnectionPoolMax' "
@@ -295,6 +296,16 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsInteger "
                        "SINGLE-VALUE )",
                NULL, NULL },
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+       { "session-tracking-request", "true|FALSE", 2, 2, 0,
+               ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_ST_REQUEST,
+               ldap_back_cf_gen, "( OLcfgDbAt:3.24 "
+                       "NAME 'olcDbSessionTrackingRequest' "
+                       "DESC 'Add session tracking control to proxied requests' "
+                       "SYNTAX OMsBoolean "
+                       "SINGLE-VALUE )",
+               NULL, NULL },
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
        { "suffixmassage", "[virtual]> <real", 2, 3, 0,
                ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
                ldap_back_cf_gen, NULL, NULL, NULL },
@@ -1117,6 +1128,12 @@ ldap_back_cf_gen( ConfigArgs *c )
                        }
                        break;
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+               case LDAP_BACK_CFG_ST_REQUEST:
+                       c->value_int = LDAP_BACK_ST_REQUEST( li );
+                       break;
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
                default:
                        /* FIXME: we need to handle all... */
                        assert( 0 );
@@ -1233,6 +1250,12 @@ ldap_back_cf_gen( ConfigArgs *c )
                        li->li_flags &= ~LDAP_BACK_F_QUARANTINE;
                        break;
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+               case LDAP_BACK_CFG_ST_REQUEST:
+                       li->li_flags &= ~LDAP_BACK_F_ST_REQUEST;
+                       break;
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
                default:
                        /* FIXME: we need to handle all... */
                        assert( 0 );
@@ -1866,6 +1889,17 @@ done_url:;
                }
                break;
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+       case LDAP_BACK_CFG_ST_REQUEST:
+               if ( c->value_int ) {
+                       li->li_flags |= LDAP_BACK_F_ST_REQUEST;
+
+               } else {
+                       li->li_flags &= ~LDAP_BACK_F_ST_REQUEST;
+               }
+               break;
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
        case LDAP_BACK_CFG_REWRITE:
                snprintf( c->cr_msg, sizeof( c->cr_msg ),
                        "rewrite/remap capabilities have been moved "
index 4f1e67ddf87e4a68bb442e1bac69587764596024..f10c7d0bbbbe22461052bb33ae2f5a3cd67aa17c 100644 (file)
@@ -50,8 +50,7 @@ ldap_back_delete(
 
 retry:
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-               li->li_version, &li->li_idassert, op, rs, &ctrls );
+       rc = ldap_back_controls_add( op, rs, lc, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
                rc = rs->sr_err;
@@ -67,13 +66,13 @@ retry:
                retrying &= ~LDAP_BACK_RETRYING;
                if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        if ( lc != NULL ) {
                ldap_back_release_conn( li, lc );
index 06f374ae3c45d4c6eaa6b3fa3162318c0eb6feba..cf3aacbb71ebf2504c1b3ef1523b7ac48b92d6e0 100644 (file)
@@ -47,7 +47,7 @@ ldap_back_extended_one( Operation *op, SlapReply *rs, ldap_back_exop_f exop )
        ldapinfo_t      *li = (ldapinfo_t *) op->o_bd->be_private;
 
        ldapconn_t      *lc = NULL;
-       LDAPControl     **oldctrls = NULL;
+       LDAPControl     **ctrls = NULL, **oldctrls = NULL;
        int             rc;
 
        /* FIXME: this needs to be called here, so it is
@@ -58,9 +58,8 @@ ldap_back_extended_one( Operation *op, SlapReply *rs, ldap_back_exop_f exop )
                return -1;
        }
 
-       oldctrls = op->o_ctrls;
-       if ( ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-               li->li_version, &li->li_idassert, op, rs, &op->o_ctrls ) )
+       ctrls = op->o_ctrls;
+       if ( ldap_back_controls_add( op, rs, lc, &ctrls ) )
        {
                op->o_ctrls = oldctrls;
                send_ldap_extended( op, rs );
@@ -70,13 +69,11 @@ ldap_back_extended_one( Operation *op, SlapReply *rs, ldap_back_exop_f exop )
                goto done;
        }
 
+       op->o_ctrls = ctrls;
        rc = exop( op, rs, &lc );
 
-       if ( op->o_ctrls && op->o_ctrls != oldctrls ) {
-               free( op->o_ctrls[ 0 ] );
-               free( op->o_ctrls );
-       }
        op->o_ctrls = oldctrls;
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
 done:;
        if ( lc != NULL ) {
index fc247cb571c65b4331bc975e450000f832d396b8..7b5817f0665df164f345603acf20e353051e5bb7 100644 (file)
@@ -99,8 +99,7 @@ ldap_back_modify(
 
 retry:;
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-               li->li_version, &li->li_idassert, op, rs, &ctrls );
+       rc = ldap_back_controls_add( op, rs, lc, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
                rc = -1;
@@ -116,13 +115,13 @@ retry:;
                retrying &= ~LDAP_BACK_RETRYING;
                if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:;
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        for ( i = 0; modv[ i ]; i++ ) {
                ch_free( modv[ i ]->mod_bvalues );
index 8fa02ef6e2a216c6f6cc430095a7984433ec1e91..d6e3b018542093f10c2d6d51c6e72f1e1675cb12 100644 (file)
@@ -74,8 +74,7 @@ ldap_back_modrdn(
 
 retry:
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-               li->li_version, &li->li_idassert, op, rs, &ctrls );
+       rc = ldap_back_controls_add( op, rs, lc, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
                rc = -1;
@@ -92,13 +91,13 @@ retry:
                retrying &= ~LDAP_BACK_RETRYING;
                if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        if ( lc != NULL ) {
                ldap_back_release_conn( li, lc );
index 8eca7f6593a204e53e5e4d0eb76b255754f04b5e..9bc413338735ec3ea5d5b374621a40014dad91cf 100644 (file)
@@ -63,6 +63,7 @@ extern void ldap_back_conn_free( void *c );
 
 extern ldapconn_t * ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc );
 
+#if 0
 extern int
 ldap_back_proxy_authz_ctrl(
                struct berval   *bound_ndn,
@@ -76,6 +77,26 @@ extern int
 ldap_back_proxy_authz_ctrl_free(
                Operation       *op,
                LDAPControl     ***pctrls );
+#endif
+
+extern int
+ldap_back_proxy_authz_ctrl(
+               Operation       *op,
+               SlapReply       *rs,
+               struct berval   *bound_ndn,
+               int             version,
+               slap_idassert_t *si,
+               LDAPControl     *ctrl );
+
+extern int
+ldap_back_controls_add(
+               Operation       *op,
+               SlapReply       *rs,
+               ldapconn_t      *lc,
+               LDAPControl     ***pctrls );
+
+extern int
+ldap_back_controls_free( Operation *op, SlapReply *rs, LDAPControl ***pctrls );
 
 extern void
 ldap_back_quarantine(
index 732fb203e7c5d72578a6e0df9cb19e42baa67edb..4c4f078fb1442d45dfa8853506eb5430b4ee4ae9 100644 (file)
@@ -205,8 +205,7 @@ ldap_back_search(
        }
 
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-               li->li_version, &li->li_idassert, op, rs, &ctrls );
+       rc = ldap_back_controls_add( op, rs, lc, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                goto finish;
        }
@@ -529,7 +528,7 @@ finish:;
                send_ldap_result( op, rs );
        }
 
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        if ( rs->sr_ctrls ) {
                ldap_controls_free( rs->sr_ctrls );
@@ -819,8 +818,7 @@ ldap_back_entry_get(
 
 retry:
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( &lc->lc_bound_ndn,
-               li->li_version, &li->li_idassert, op, &rs, &ctrls );
+       rc = ldap_back_controls_add( op, &rs, lc, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                goto cleanup;
        }
@@ -833,7 +831,7 @@ retry:
                        do_retry = 0;
                        if ( ldap_back_retry( &lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
                                /* if the identity changed, there might be need to re-authz */
-                               (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                               (void)ldap_back_controls_free( op, &rs, &ctrls );
                                goto retry;
                        }
                }
@@ -860,7 +858,7 @@ retry:
        }
 
 cleanup:
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, &rs, &ctrls );
 
        if ( result ) {
                ldap_msgfree( result );
index ddd651f7a9d6a63b0a3b2ea29a721a0e98f0435f..cfa3e73f5a8367d2bc3a2c12e03ed23bbbea2d52 100644 (file)
@@ -169,8 +169,7 @@ meta_back_add( Operation *op, SlapReply *rs )
 
 retry:;
        ctrls = op->o_ctrls;
-       if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-               mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
+       if ( meta_back_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS )
        {
                send_ldap_result( op, rs );
                goto cleanup;
@@ -184,13 +183,13 @@ retry:;
                do_retry = 0;
                if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:;
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        for ( --i; i >= 0; --i ) {
                free( attrs[ i ]->mod_bvalues );
index dbceee049e82392a29211f27b1cbb4d961c07e23..2f7b080e8ba0f31562f704f9d9ebf18cd124f7f3 100644 (file)
@@ -310,6 +310,11 @@ typedef struct metatarget_t {
 #define        META_BACK_TGT_CANCEL_DISCOVER(mt)       META_BACK_TGT_ISMASK( (mt), LDAP_BACK_F_CANCEL_MASK2, LDAP_BACK_F_CANCEL_EXOP_DISCOVER )
 #define        META_BACK_TGT_QUARANTINE(mt)            META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_QUARANTINE )
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+#define        META_BACK_TGT_ST_REQUEST(mt)            META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_ST_REQUEST )
+#define        META_BACK_TGT_ST_RESPONSE(mt)           META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_ST_RESPONSE )
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
        int                     mt_version;
        time_t                  mt_network_timeout;
        struct timeval          mt_bind_timeout;
index 03e3ec204eb33d8e2975770f3871516ed0272c51..bae5a477829799959517cfca5f2ea6072803a2b7 100644 (file)
@@ -460,6 +460,9 @@ meta_back_single_bind(
        metasingleconn_t        *msc = &mc->mc_conns[ candidate ];
        int                     msgid;
        dncookie                dc;
+       struct berval           save_o_dn;
+       int                     save_o_do_not_cache;
+       LDAPControl             **ctrls = NULL;
        
        if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
                ch_free( msc->msc_bound_ndn.bv_val );
@@ -487,6 +490,20 @@ meta_back_single_bind(
                return rs->sr_err;
        }
 
+       /* don't add proxyAuthz; set the bindDN */
+       save_o_dn = op->o_dn;
+       save_o_do_not_cache = op->o_do_not_cache;
+       op->o_do_not_cache = 1;
+       op->o_dn = op->o_req_dn;
+
+       ctrls = op->o_ctrls;
+       rs->sr_err = meta_back_controls_add( op, rs, mc, candidate, &ctrls );
+       op->o_dn = save_o_dn;
+       op->o_do_not_cache = save_o_do_not_cache;
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               goto return_results;
+       }
+
        /* FIXME: this fixes the bind problem right now; we need
         * to use the asynchronous version to get the "matched"
         * and more in case of failure ... */
@@ -495,12 +512,15 @@ meta_back_single_bind(
        for (;;) {
                rs->sr_err = ldap_sasl_bind( msc->msc_ld, mdn.bv_val,
                        LDAP_SASL_SIMPLE, &op->orb_cred,
-                       op->o_ctrls, NULL, &msgid );
+                       ctrls, NULL, &msgid );
                if ( rs->sr_err != LDAP_X_CONNECTING ) {
                        break;
                }
                ldap_pvt_thread_yield();
        }
+
+       ldap_back_controls_free( op, rs, &ctrls );
+
        meta_back_bind_op_result( op, rs, mc, candidate, msgid, LDAP_BACK_DONTSEND );
        if ( rs->sr_err != LDAP_SUCCESS ) {
                goto return_results;
@@ -1537,3 +1557,120 @@ meta_back_proxy_authz_bind( metaconn_t *mc, int candidate, Operation *op, SlapRe
 
        return LDAP_BACK_CONN_ISBOUND( msc );
 }
+
+/*
+ * Add controls;
+ *
+ * if any needs to be added, it is prepended to existing ones,
+ * in a newly allocated array.  The companion function
+ * ldap_back_controls_free() must be used to restore the original
+ * status of op->o_ctrls.
+ */
+int
+meta_back_controls_add(
+               Operation       *op,
+               SlapReply       *rs,
+               metaconn_t      *mc,
+               int             candidate,
+               LDAPControl     ***pctrls )
+{
+       metainfo_t              *mi = (metainfo_t *)op->o_bd->be_private;
+       metatarget_t            *mt = mi->mi_targets[ candidate ];
+       metasingleconn_t        *msc = &mc->mc_conns[ candidate ];
+
+       LDAPControl             **ctrls = NULL;
+       /* set to the maximum number of controls this backend can add */
+       LDAPControl             c[ 2 ] = { 0 };
+       int                     i = 0, j = 0;
+
+       *pctrls = NULL;
+
+       rs->sr_err = LDAP_SUCCESS;
+
+       /* don't add controls if protocol is not LDAPv3 */
+       switch ( mt->mt_version ) {
+       case LDAP_VERSION3:
+               break;
+
+       case 0:
+               if ( op->o_protocol == 0 || op->o_protocol == LDAP_VERSION3 ) {
+                       break;
+               }
+               /* fall thru */
+
+       default:
+               goto done;
+       }
+
+       /* proxyAuthz for identity assertion */
+       switch ( ldap_back_proxy_authz_ctrl( op, rs, &msc->msc_bound_ndn,
+               mt->mt_version, &mt->mt_idassert, &c[ j ] ) )
+       {
+       case SLAP_CB_CONTINUE:
+               break;
+
+       case LDAP_SUCCESS:
+               j++;
+               break;
+
+       default:
+               goto done;
+       }
+
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+       /* session tracking */
+       if ( META_BACK_TGT_ST_REQUEST( mt ) ) {
+               switch ( slap_ctrl_session_tracking_request_add( op, rs, &c[ j ] ) ) {
+               case SLAP_CB_CONTINUE:
+                       break;
+
+               case LDAP_SUCCESS:
+                       j++;
+                       break;
+
+               default:
+                       goto done;
+               }
+       }
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
+       if ( rs->sr_err == SLAP_CB_CONTINUE ) {
+               rs->sr_err = LDAP_SUCCESS;
+       }
+
+       if ( j == 0 ) {
+               goto done;
+       }
+
+       if ( op->o_ctrls ) {
+               for ( i = 0; op->o_ctrls[ i ]; i++ )
+                       /* just count ctrls */ ;
+       }
+
+       ctrls = op->o_tmpalloc( sizeof( LDAPControl * ) * (i + j + 1) + j * sizeof( LDAPControl ),
+                       op->o_tmpmemctx );
+       ctrls[ 0 ] = (LDAPControl *)&ctrls[ i + j + 1 ];
+       *ctrls[ 0 ] = c[ 0 ];
+       for ( i = 1; i < j; i++ ) {
+               ctrls[ i ] = &ctrls[ 0 ][ i ];
+               *ctrls[ i ] = c[ i ];
+       }
+
+       i = 0;
+       if ( op->o_ctrls ) {
+               for ( i = 0; op->o_ctrls[ i ]; i++ ) {
+                       ctrls[ i + j ] = op->o_ctrls[ i ];
+               }
+       }
+       ctrls[ i + j ] = NULL;
+
+done:;
+       if ( ctrls == NULL ) {
+               ctrls = op->o_ctrls;
+       }
+
+       *pctrls = ctrls;
+       
+       return rs->sr_err;
+}
+
index 0a8cf10e6bf7803ac194220ba7cfb4a2d3f74e02..b381daf89eb315bef307f576b2bb1f89851fae79 100644 (file)
@@ -113,8 +113,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
 
 retry:;
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-               mt->mt_version, &mt->mt_idassert, op, rs, &ctrls );
+       rc = meta_back_controls_add( op, rs, mc, candidate, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
                goto cleanup;
@@ -130,13 +129,13 @@ retry:;
                do_retry = 0;
                if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:;
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        if ( mdn.bv_val != op->o_req_dn.bv_val ) {
                free( mdn.bv_val );
index 0725a415d60f415bd5eb148197ee5e9125186680..6cdfbc60fc85a67824032040beaeecb3fc5ed25c 100644 (file)
@@ -1235,6 +1235,36 @@ idassert-authzFrom       "dn:<rootdn>"
                } else {
                        mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags |= LDAP_BACK_F_QUARANTINE;
                }
+
+       /* session tracking request */
+       } else if ( strcasecmp( argv[ 0 ], "session-tracking-request" ) == 0 ) {
+               unsigned        *flagsp = mi->mi_ntargets ?
+                               &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_flags
+                               : &mi->mi_flags;
+
+               if ( argc != 2 ) {
+                       Debug( LDAP_DEBUG_ANY,
+       "%s: line %d: \"session-tracking-request {TRUE|false}\" needs 1 argument.\n",
+                               fname, lineno, 0 );
+                       return( 1 );
+               }
+
+               /* this is the default; we add it because the default might change... */
+               switch ( check_true_false( argv[ 1 ] ) ) {
+               case 1:
+                       *flagsp |= LDAP_BACK_F_ST_REQUEST;
+                       break;
+
+               case 0:
+                       *flagsp &= ~LDAP_BACK_F_ST_REQUEST;
+                       break;
+
+               default:
+                       Debug( LDAP_DEBUG_ANY,
+               "%s: line %d: \"session-tracking-request {TRUE|false}\": unknown argument \"%s\".\n",
+                               fname, lineno, argv[ 1 ] );
+                       return( 1 );
+               }
        
        /* dn massaging */
        } else if ( strcasecmp( argv[ 0 ], "suffixmassage" ) == 0 ) {
index 8f1eaac21b794ae66fa905441342b7ceea9cc7ae..da4d7553cd7b49b64051ba7578c7b65e1e40eb6b 100644 (file)
@@ -67,8 +67,7 @@ meta_back_delete( Operation *op, SlapReply *rs )
 
 retry:;
        ctrls = op->o_ctrls;
-       if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-               mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
+       if ( meta_back_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS )
        {
                send_ldap_result( op, rs );
                goto cleanup;
@@ -82,13 +81,13 @@ retry:;
                do_retry = 0;
                if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:;
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        if ( mdn.bv_val != op->o_req_dn.bv_val ) {
                free( mdn.bv_val );
index a1088c793279b9426497d11e8244c7934940f2d5..ef117860e0bd2dbd8a0281bbf7ca197ee398d497 100644 (file)
@@ -178,8 +178,7 @@ meta_back_modify( Operation *op, SlapReply *rs )
 
 retry:;
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-               mt->mt_version, &mt->mt_idassert, op, rs, &ctrls );
+       rc = meta_back_controls_add( op, rs, mc, candidate, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
                goto cleanup;
@@ -193,13 +192,13 @@ retry:;
                do_retry = 0;
                if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:;
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        if ( mdn.bv_val != op->o_req_dn.bv_val ) {
                free( mdn.bv_val );
index 2a14b272085af0f9aaad7ec76bd6491871357d3d..66222cfefda2caeabbd255182585dddf34638db4 100644 (file)
@@ -120,8 +120,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
 
 retry:;
        ctrls = op->o_ctrls;
-       if ( ldap_back_proxy_authz_ctrl( &mc->mc_conns[ candidate ].msc_bound_ndn,
-               mt->mt_version, &mt->mt_idassert, op, rs, &ctrls ) != LDAP_SUCCESS )
+       if ( meta_back_controls_add( op, rs, mc, candidate, &ctrls ) != LDAP_SUCCESS )
        {
                send_ldap_result( op, rs );
                goto cleanup;
@@ -137,13 +136,13 @@ retry:;
                do_retry = 0;
                if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
        }
 
 cleanup:;
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        if ( mdn.bv_val != op->o_req_dn.bv_val ) {
                free( mdn.bv_val );
index 713a87676147336803a2ebe6c2130c591af0b63a..c9e435b41d08cdf48f0e7605ca3a5ec021357e5b 100644 (file)
@@ -598,8 +598,7 @@ meta_back_search_start(
 
 retry:;
        ctrls = op->o_ctrls;
-       if ( ldap_back_proxy_authz_ctrl( &msc->msc_bound_ndn,
-               mt->mt_version, &mt->mt_idassert, op, rs, &ctrls )
+       if ( meta_back_controls_add( op, rs, *mcp, candidate, &ctrls )
                != LDAP_SUCCESS )
        {
                candidates[ candidate ].sr_msgid = META_MSGID_IGNORE;
@@ -625,7 +624,7 @@ retry:;
                if ( nretries && meta_back_retry( op, rs, mcp, candidate, LDAP_BACK_DONTSEND ) ) {
                        nretries = 0;
                        /* if the identity changed, there might be need to re-authz */
-                       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+                       (void)ldap_back_controls_free( op, rs, &ctrls );
                        goto retry;
                }
 
@@ -642,7 +641,7 @@ retry:;
        }
 
 done:;
-       (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+       (void)ldap_back_controls_free( op, rs, &ctrls );
 
        if ( mapped_attrs ) {
                free( mapped_attrs );
index 13dcab4de627cbdc1b44fe6d0b048569a5567cbb..ed887e5f1a4b27ced92bc7ca4e43c8112720d5df 100644 (file)
@@ -21,6 +21,7 @@
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "ldif.h"
 #include "lutil.h"
 
 #include "../../libraries/liblber/lber-int.h"
@@ -1755,18 +1756,19 @@ static int parseSessionTracking(
        } else {
                /* note: should not be more than 65536... */
                tag = ber_scanf( ber, "m", &sessionTrackingIdentifier );
-       }
-
-       if ( ldif_is_not_printable( sessionTrackingIdentifier.bv_val, sessionTrackingIdentifier.bv_len ) ) {
-               /* we want the OID printed, at least */
-               BER_BVSTR( &sessionTrackingIdentifier, "" );
+               if ( ldif_is_not_printable( sessionTrackingIdentifier.bv_val, sessionTrackingIdentifier.bv_len ) ) {
+                       /* we want the OID printed, at least */
+                       BER_BVSTR( &sessionTrackingIdentifier, "" );
+               }
        }
 
        /* closure */
        tag = ber_skip_tag( ber, &len );
-       if ( tag == LBER_DEFAULT && len == 0 ) {
-               tag = 0;
+       if ( tag != LBER_DEFAULT || len != 0 ) {
+               tag = LBER_ERROR;
+               goto error;
        }
+       tag = 0;
 
        st_len = 0;
        if ( !BER_BVISNULL( &sessionSourceIp ) ) {
@@ -1830,4 +1832,73 @@ error:;
 
        return rs->sr_err;
 }
+
+int
+slap_ctrl_session_tracking_add(
+       Operation *op,
+       SlapReply *rs,
+       struct berval *ip,
+       struct berval *name,
+       struct berval *id,
+       LDAPControl *ctrl )
+{
+       BerElementBuffer berbuf;
+       BerElement      *ber = (BerElement *)&berbuf;
+
+       static struct berval    oid = BER_BVC( LDAP_CONTROL_X_SESSION_TRACKING_USERNAME );
+
+       assert( ctrl != NULL );
+
+       ber_init2( ber, NULL, LBER_USE_DER );
+
+       ber_printf( ber, "{OOOO}", ip, name, &oid, id ); 
+
+       if ( ber_flatten2( ber, &ctrl->ldctl_value, 0 ) == -1 ) {
+               rs->sr_err = LDAP_OTHER;
+               goto done;
+       }
+
+       ctrl->ldctl_oid = LDAP_CONTROL_X_SESSION_TRACKING;
+       ctrl->ldctl_iscritical = 0;
+
+       rs->sr_err = LDAP_SUCCESS;
+
+done:;
+       return rs->sr_err;
+}
+
+int
+slap_ctrl_session_tracking_request_add( Operation *op, SlapReply *rs, LDAPControl *ctrl )
+{
+       static struct berval    bv_unknown = BER_BVC( SLAP_STRING_UNKNOWN );
+       struct berval           ip = BER_BVNULL,
+                               name = BER_BVNULL,
+                               id = BER_BVNULL;
+
+       if ( !BER_BVISNULL( &op->o_conn->c_peer_name ) &&
+               memcmp( op->o_conn->c_peer_name.bv_val, "IP=", STRLENOF( "IP=" ) ) == 0 )
+       {
+               char    *ptr;
+
+               ip.bv_val = op->o_conn->c_peer_name.bv_val + STRLENOF( "IP=" );
+               ip.bv_len = op->o_conn->c_peer_name.bv_len - STRLENOF( "IP=" );
+
+               ptr = ber_bvchr( &ip, ':' );
+               if ( ptr ) {
+                       ip.bv_len = ptr - ip.bv_val;
+               }
+       }
+
+       if ( !BER_BVISNULL( &op->o_conn->c_peer_domain ) &&
+               !bvmatch( &op->o_conn->c_peer_domain, &bv_unknown ) )
+       {
+               name = op->o_conn->c_peer_domain;
+       }
+
+       if ( !BER_BVISNULL( &op->o_dn ) && !BER_BVISEMPTY( &op->o_dn ) ) {
+               id = op->o_dn;
+       }
+
+       return slap_ctrl_session_tracking_add( op, rs, &ip, &name, &id, ctrl );
+}
 #endif
index 499fc06c895ee9036e65d49da878458cc791e712..40d27139522b90ca82886b8e4c8df122ebe077d1 100644 (file)
 # include <tcpd.h>
 int allow_severity = LOG_INFO;
 int deny_severity = LOG_NOTICE;
-
-# define SLAP_STRING_UNKNOWN   STRING_UNKNOWN
-#else /* ! TCP Wrappers */
-# define SLAP_STRING_UNKNOWN   "unknown"
-#endif /* ! TCP Wrappers */
+#endif /* TCP Wrappers */
 
 #ifdef LDAP_PF_LOCAL
 # include <sys/stat.h>
index 2e796c08d49801186b2612a14a2153b46696fe34..9eb6c9a86dd1cc5e517d90b9dca1d72befb6db3a 100644 (file)
@@ -629,6 +629,20 @@ LDAP_SLAPD_F (int) slap_remove_control LDAP_P((
        int             ctrl,
        BI_chk_controls fnc ));
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+LDAP_SLAPD_F (int)
+slap_ctrl_session_tracking_add LDAP_P((
+       Operation *op,
+       SlapReply *rs,
+       struct berval *ip,
+       struct berval *name,
+       struct berval *id,
+       LDAPControl *ctrl ));
+LDAP_SLAPD_F (int)
+slap_ctrl_session_tracking_request_add LDAP_P((
+       Operation *op, SlapReply *rs, LDAPControl *ctrl ));
+#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
+
 /*
  * config.c
  */
index 818a36bbac5c6b51e4393abd0430472f42f855f8..75aa25d1a92b32aa292b047133e3796b19988f88 100644 (file)
@@ -101,6 +101,13 @@ LDAP_BEGIN_DECL
 #define SERVICE_NAME  OPENLDAP_PACKAGE "-slapd"
 #define SLAPD_ANONYMOUS ""
 
+#ifdef HAVE_TCPD
+# include <tcpd.h>
+# define SLAP_STRING_UNKNOWN   STRING_UNKNOWN
+#else /* ! TCP Wrappers */
+# define SLAP_STRING_UNKNOWN   "unknown"
+#endif /* ! TCP Wrappers */
+
 /* LDAPMod.mod_op value ===> Must be kept in sync with ldap.h!
  * This is a value used internally by the backends. It is needed to allow
  * adding values that already exist without getting an error as required by