add support for session tracking (draft-wahl-ldap-sessio) to proxy backends requests

This commit is contained in:
Pierangelo Masarati 2007-08-22 15:49:35 +00:00
parent 63b6bfd1a4
commit 9a00bbb35f
26 changed files with 563 additions and 147 deletions

View 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.

View 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.

View 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 ) {

View 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;

View 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 );

View 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 );

View 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 "

View 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 );

View 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 ) {

View 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 );

View 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 );

View 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(

View 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 );

View 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 );

View 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;

View 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;
}

View 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 );

View 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 ) {

View 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 );

View 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 );

View 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 );

View 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 );

View 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

View file

@ -53,11 +53,7 @@
# 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>

View 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
*/

View 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