From c6f12694fc959cde780fe83adfa535cce7998b89 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 7 Jul 2008 21:25:59 +0000 Subject: [PATCH] allow proxies to filter out search references (ITS#5593) --- doc/man/man5/slapd-ldap.5 | 7 +++++++ doc/man/man5/slapd-meta.5 | 9 +++++++++ servers/slapd/back-ldap/back-ldap.h | 4 ++++ servers/slapd/back-ldap/config.c | 31 +++++++++++++++++++++++++++++ servers/slapd/back-ldap/search.c | 5 +++++ servers/slapd/back-meta/back-meta.h | 2 ++ servers/slapd/back-meta/config.c | 30 ++++++++++++++++++++++++++++ servers/slapd/back-meta/search.c | 4 ++++ 8 files changed, 92 insertions(+) diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5 index a65d1b6534..4ce6d21795 100644 --- a/doc/man/man5/slapd-ldap.5 +++ b/doc/man/man5/slapd-ldap.5 @@ -384,6 +384,13 @@ returns in case of no activity. The value is in seconds, and it can be specified as for .BR idle-timeout . +.TP +.B norefs +If +.BR yes , +do not return search reference responses. +By default, they are returned unless request is LDAPv2. + .TP .B protocol\-version {0,2,3} This directive indicates what protocol version must be used to contact diff --git a/doc/man/man5/slapd-meta.5 b/doc/man/man5/slapd-meta.5 index 59488c2be5..897578c22f 100644 --- a/doc/man/man5/slapd-meta.5 +++ b/doc/man/man5/slapd-meta.5 @@ -127,6 +127,15 @@ If the value is set to \fBreport\fP, the search is continuated to the end but, in case at least one target returned an error code, the first non-success error code is returned. +.TP +.B norefs +If +.BR yes , +do not return search reference responses. +By default, they are returned unless request is LDAPv2. +If set before any target specification, it affects all targets, unless +overridden by any per-target directive. + .TP .B protocol\-version {0,2,3} This directive indicates what protocol version must be used to contact diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 81a42501f0..dedbe9da92 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -315,6 +315,8 @@ typedef struct ldapinfo_t { #define LDAP_BACK_F_ST_RESPONSE (0x00040000U) #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ +#define LDAP_BACK_F_NOREFS (0x00080000U) + #define LDAP_BACK_ISSET_F(ff,f) ( ( (ff) & (f) ) == (f) ) #define LDAP_BACK_ISMASK_F(ff,m,f) ( ( (ff) & (m) ) == (f) ) @@ -353,6 +355,8 @@ typedef struct ldapinfo_t { #define LDAP_BACK_ST_RESPONSE(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_ST_RESPONSE) #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ +#define LDAP_BACK_NOREFS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_NOREFS) + int li_version; /* cached connections; diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 9f1659e7d0..bf8a8ff253 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -70,6 +70,8 @@ enum { LDAP_BACK_CFG_CANCEL, LDAP_BACK_CFG_QUARANTINE, LDAP_BACK_CFG_ST_REQUEST, + LDAP_BACK_CFG_NOREFS, + LDAP_BACK_CFG_REWRITE, LDAP_BACK_CFG_LAST @@ -306,6 +308,14 @@ static ConfigTable ldapcfg[] = { "SINGLE-VALUE )", NULL, NULL }, #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ + { "norefs", "true|FALSE", 2, 2, 0, + ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_NOREFS, + ldap_back_cf_gen, "( OLcfgDbAt:3.25 " + "NAME 'olcDbNorefs' " + "DESC 'Do not return search reference responses' " + "SYNTAX OMsBoolean " + "SINGLE-VALUE )", + NULL, NULL }, { "suffixmassage", "[virtual]> value_int = LDAP_BACK_NOREFS( li ); + break; + default: /* FIXME: we need to handle all... */ assert( 0 ); @@ -1256,6 +1274,10 @@ ldap_back_cf_gen( ConfigArgs *c ) break; #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ + case LDAP_BACK_CFG_NOREFS: + li->li_flags &= ~LDAP_BACK_F_NOREFS; + break; + default: /* FIXME: we need to handle all... */ assert( 0 ); @@ -1900,6 +1922,15 @@ done_url:; break; #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ + case LDAP_BACK_CFG_NOREFS: + if ( c->value_int ) { + li->li_flags |= LDAP_BACK_F_NOREFS; + + } else { + li->li_flags &= ~LDAP_BACK_F_NOREFS; + } + break; + case LDAP_BACK_CFG_REWRITE: snprintf( c->cr_msg, sizeof( c->cr_msg ), "rewrite/remap capabilities have been moved " diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 3dcbcb65be..79549b22aa 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -363,6 +363,11 @@ retry: } } else if ( rc == LDAP_RES_SEARCH_REFERENCE ) { + if ( LDAP_BACK_NOREFS( li ) ) { + ldap_msgfree( res ); + continue; + } + do_retry = 0; rc = ldap_parse_reference( lc->lc_ld, res, &references, &rs->sr_ctrls, 1 ); diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 16d952bcb6..8e73c1f272 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -315,6 +315,8 @@ typedef struct metatarget_t { #define META_BACK_TGT_ST_RESPONSE(mt) META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_ST_RESPONSE ) #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ +#define META_BACK_TGT_NOREFS(mt) META_BACK_TGT_ISSET( (mt), LDAP_BACK_F_NOREFS ) + int mt_version; time_t mt_network_timeout; struct timeval mt_bind_timeout; diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 1c02ccc248..52795400ef 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -1453,6 +1453,36 @@ idassert-authzFrom "dn:" return 1; } + /* do not return search references */ + } else if ( strcasecmp( argv[ 0 ], "norefs" ) == 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: \"norefs {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_NOREFS; + break; + + case 0: + *flagsp &= ~LDAP_BACK_F_NOREFS; + break; + + default: + Debug( LDAP_DEBUG_ANY, + "%s: line %d: \"norefs {TRUE|false}\": unknown argument \"%s\".\n", + fname, lineno, argv[ 1 ] ); + return( 1 ); + } + /* anything else */ } else { return SLAP_CONF_UNKNOWN; diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index ea5a52bcb6..1f50ce622b 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -1155,6 +1155,10 @@ really_bad:; char **references = NULL; int cnt; + if ( META_BACK_TGT_NOREFS( mi->mi_targets[ i ] ) ) { + continue; + } + if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { /* don't retry any more... */ candidates[ i ].sr_type = REP_RESULT; -- 2.39.5