From f75825881a477b0416acf22913b8c609d3d4b3d2 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Fri, 9 Apr 2010 22:47:55 +0000 Subject: [PATCH] honor X-ORDERED in olcDbIdAssertAuthzFrom; add olcDbIdAssertPassthru (ITS#6456); note: breaks binary compatibility with module back-meta.la --- servers/slapd/back-ldap/back-ldap.h | 4 + servers/slapd/back-ldap/bind.c | 59 ++++++--- servers/slapd/back-ldap/config.c | 176 +++++++++++++++++++++++++-- servers/slapd/back-ldap/init.c | 1 + servers/slapd/back-ldap/proto-ldap.h | 1 + 5 files changed, 210 insertions(+), 31 deletions(-) diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index e5d43d107e..4ffb34da2d 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -238,6 +238,9 @@ typedef struct slap_idassert_t { BerVarray si_authz; #define li_idassert_authz li_idassert.si_authz + + BerVarray si_passthru; +#define li_idassert_passthru li_idassert.si_passthru } slap_idassert_t; /* @@ -448,6 +451,7 @@ typedef struct ldap_extra_t { int version, slap_idassert_t *si, LDAPControl *ctrl ); int (*controls_free)( Operation *op, SlapReply *rs, LDAPControl ***pctrls ); int (*idassert_authzfrom_parse_cf)( const char *fname, int lineno, const char *arg, slap_idassert_t *si ); + int (*idassert_passthru_parse_cf)( const char *fname, int lineno, const char *arg, slap_idassert_t *si ); int (*idassert_parse_cf)( const char *fname, int lineno, int argc, char *argv[], slap_idassert_t *si ); void (*retry_info_destroy)( slap_retry_info_t *ri ); int (*retry_info_parse)( char *in, slap_retry_info_t *ri, char *buf, ber_len_t buflen ); diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 8e74ad01d6..71a44d60e5 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -2057,32 +2057,51 @@ ldap_back_is_proxy_authz( Operation *op, SlapReply *rs, ldap_back_send_t sendok, goto done; - } else if ( li->li_idassert_authz && !be_isroot( op ) ) { - struct berval authcDN; + } else if ( !be_isroot( op ) ) { + if ( li->li_idassert_passthru ) { + struct berval authcDN; - if ( BER_BVISNULL( &ndn ) ) { - authcDN = slap_empty_bv; - - } else { - authcDN = ndn; - } - rs->sr_err = slap_sasl_matches( op, li->li_idassert_authz, - &authcDN, &authcDN ); - if ( rs->sr_err != LDAP_SUCCESS ) { - if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { - if ( sendok & LDAP_BACK_SENDERR ) { - send_ldap_result( op, rs ); - dobind = -1; - } + if ( BER_BVISNULL( &ndn ) ) { + authcDN = slap_empty_bv; } else { - rs->sr_err = LDAP_SUCCESS; - *binddn = slap_empty_bv; - *bindcred = slap_empty_bv; + authcDN = ndn; + } + rs->sr_err = slap_sasl_matches( op, li->li_idassert_passthru, + &authcDN, &authcDN ); + if ( rs->sr_err == LDAP_SUCCESS ) { + dobind = 0; break; } + } - goto done; + if ( li->li_idassert_authz ) { + struct berval authcDN; + + if ( BER_BVISNULL( &ndn ) ) { + authcDN = slap_empty_bv; + + } else { + authcDN = ndn; + } + rs->sr_err = slap_sasl_matches( op, li->li_idassert_authz, + &authcDN, &authcDN ); + if ( rs->sr_err != LDAP_SUCCESS ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { + if ( sendok & LDAP_BACK_SENDERR ) { + send_ldap_result( op, rs ); + dobind = -1; + } + + } else { + rs->sr_err = LDAP_SUCCESS; + *binddn = slap_empty_bv; + *bindcred = slap_empty_bv; + break; + } + + goto done; + } } } diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 16780dff19..14eca16ba3 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -54,6 +54,7 @@ enum { LDAP_BACK_CFG_IDASSERT_AUTHCDN, LDAP_BACK_CFG_IDASSERT_PASSWD, LDAP_BACK_CFG_IDASSERT_AUTHZFROM, + LDAP_BACK_CFG_IDASSERT_PASSTHRU, LDAP_BACK_CFG_IDASSERT_METHOD, LDAP_BACK_CFG_IDASSERT_BIND, LDAP_BACK_CFG_REBIND, @@ -185,6 +186,7 @@ static ConfigTable ldapcfg[] = { ldap_back_cf_gen, "( OLcfgDbAt:3.9 " "NAME 'olcDbIDAssertAuthzFrom' " "DESC 'Remote Identity Assertion authz rules' " + "EQUALITY caseIgnoreMatch " "SYNTAX OMsDirectoryString " "X-ORDERED 'VALUES' )", NULL, NULL }, @@ -326,6 +328,16 @@ static ConfigTable ldapcfg[] = { "SYNTAX OMsBoolean " "SINGLE-VALUE )", NULL, NULL }, + { "idassert-passThru", "authzRule", 2, 2, 0, + ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSTHRU, + ldap_back_cf_gen, "( OLcfgDbAt:3.27 " + "NAME 'olcDbIDAssertPassThru' " + "DESC 'Remote Identity Assertion passthru rules' " + "EQUALITY caseIgnoreMatch " + "SYNTAX OMsDirectoryString " + "X-ORDERED 'VALUES' )", + NULL, NULL }, + { "suffixmassage", "[virtual]> log, c->cr_msg, 0 ); return 1; } + + if ( c->valx == -1 ) { + ber_bvarray_add( &si->si_authz, &bv ); + + } else { + int i; + for ( i = 0; !BER_BVISNULL( &si->si_authz[ i ] ); i++ ) + ; + + if ( i <= c->valx ) { + ber_bvarray_add( &si->si_authz, &bv ); + + } else { + BerVarray tmp = ber_memrealloc( si->si_authz, + sizeof( struct berval )*( i + 2 ) ); + if ( tmp == NULL ) { + return -1; + } + si->si_authz = tmp; + for ( ; i > c->valx; i-- ) { + si->si_authz[ i ] = si->si_authz[ i - 1 ]; + } + si->si_authz[ c->valx ] = bv; + } + } + + return 0; +} + +static int +slap_idassert_passthru_parse( ConfigArgs *c, slap_idassert_t *si ) +{ + struct berval bv; + struct berval in; + int rc; + + ber_str2bv( c->argv[ 1 ], 0, 0, &in ); + rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL ); + if ( rc != LDAP_SUCCESS ) { + snprintf( c->cr_msg, sizeof( c->cr_msg ), + "\"idassert-passThru \": " + "invalid syntax" ); + Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); + return 1; + } - ber_bvarray_add( &si->si_authz, &bv ); + if ( c->valx == -1 ) { + ber_bvarray_add( &si->si_passthru, &bv ); + + } else { + int i; + for ( i = 0; !BER_BVISNULL( &si->si_passthru[ i ] ); i++ ) + ; + + if ( i <= c->valx ) { + ber_bvarray_add( &si->si_passthru, &bv ); + + } else { + BerVarray tmp = ber_memrealloc( si->si_passthru, + sizeof( struct berval )*( i + 2 ) ); + if ( tmp == NULL ) { + return -1; + } + si->si_passthru = tmp; + for ( ; i > c->valx; i-- ) { + si->si_passthru[ i ] = si->si_passthru[ i - 1 ]; + } + si->si_passthru[ c->valx ] = bv; + } + } return 0; } @@ -838,6 +919,22 @@ slap_idassert_authzfrom_parse_cf( const char *fname, int lineno, const char *arg return slap_idassert_authzfrom_parse( &c, si ); } +int +slap_idassert_passthru_parse_cf( const char *fname, int lineno, const char *arg, slap_idassert_t *si ) +{ + ConfigArgs c = { 0 }; + char *argv[ 3 ]; + + snprintf( c.log, sizeof( c.log ), "%s: line %d", fname, lineno ); + c.argc = 2; + c.argv = argv; + argv[ 0 ] = "idassert-passThru"; + argv[ 1 ] = (char *)arg; + argv[ 2 ] = NULL; + + return slap_idassert_passthru_parse( &c, si ); +} + int slap_idassert_parse_cf( const char *fname, int lineno, int argc, char *argv[], slap_idassert_t *si ) { @@ -939,11 +1036,23 @@ ldap_back_cf_gen( ConfigArgs *c ) rc = 1; break; - case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: { + case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: + case LDAP_BACK_CFG_IDASSERT_PASSTHRU: { + BerVarray *bvp; int i; + struct berval bv = BER_BVNULL; + char buf[SLAP_TEXT_BUFLEN]; - if ( li->li_idassert_authz == NULL ) { - if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) { + switch ( c->type ) { + case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: bvp = &li->li_idassert_authz; break; + case LDAP_BACK_CFG_IDASSERT_PASSTHRU: bvp = &li->li_idassert_passthru; break; + default: assert( 0 ); break; + } + + if ( *bvp == NULL ) { + if ( *bvp == li->li_idassert_authz + && ( li->li_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) + { BER_BVSTR( &bv, "*" ); value_add_one( &c->rvalue_vals, &bv ); @@ -953,9 +1062,18 @@ ldap_back_cf_gen( ConfigArgs *c ) break; } - for ( i = 0; !BER_BVISNULL( &li->li_idassert_authz[ i ] ); i++ ) - { - value_add_one( &c->rvalue_vals, &li->li_idassert_authz[ i ] ); + for ( i = 0; !BER_BVISNULL( &((*bvp)[ i ]) ); i++ ) { + char *ptr; + int len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i ); + bv.bv_len = ((*bvp)[ i ]).bv_len + len; + bv.bv_val = ber_memrealloc( bv.bv_val, bv.bv_len + 1 ); + ptr = bv.bv_val; + ptr = lutil_strcopy( ptr, buf ); + ptr = lutil_strncopy( ptr, ((*bvp)[ i ]).bv_val, ((*bvp)[ i ]).bv_len ); + value_add_one( &c->rvalue_vals, &bv ); + } + if ( bv.bv_val ) { + ber_memfree( bv.bv_val ); } break; } @@ -1290,11 +1408,43 @@ ldap_back_cf_gen( ConfigArgs *c ) break; case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: - if ( li->li_idassert_authz != NULL ) { - ber_bvarray_free( li->li_idassert_authz ); - li->li_idassert_authz = NULL; + case LDAP_BACK_CFG_IDASSERT_PASSTHRU: { + BerVarray *bvp; + + switch ( c->type ) { + case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: bvp = &li->li_idassert_authz; break; + case LDAP_BACK_CFG_IDASSERT_PASSTHRU: bvp = &li->li_idassert_passthru; break; + default: assert( 0 ); break; } - break; + + if ( c->valx < 0 ) { + if ( *bvp != NULL ) { + ber_bvarray_free( *bvp ); + *bvp = NULL; + } + + } else { + int i; + + if ( *bvp == NULL ) { + rc = 1; + break; + } + + for ( i = 0; !BER_BVISNULL( &((*bvp)[ i ]) ); i++ ) + ; + + if ( i >= c->valx ) { + rc = 1; + break; + } + ber_memfree( ((*bvp)[ c->valx ]).bv_val ); + for ( i = c->valx; !BER_BVISNULL( &((*bvp)[ i + 1 ]) ); i++ ) { + (*bvp)[ i ] = (*bvp)[ i + 1 ]; + } + BER_BVZERO( &((*bvp)[ i ]) ); + } + } break; case LDAP_BACK_CFG_IDASSERT_BIND: bindconf_free( &li->li_idassert.si_bc ); @@ -1735,6 +1885,10 @@ done_url:; rc = slap_idassert_authzfrom_parse( c, &li->li_idassert ); break; + case LDAP_BACK_CFG_IDASSERT_PASSTHRU: + rc = slap_idassert_passthru_parse( c, &li->li_idassert ); + break; + case LDAP_BACK_CFG_IDASSERT_METHOD: /* no longer supported */ snprintf( c->cr_msg, sizeof( c->cr_msg ), diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index 8c2110b383..5daf0bd033 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -36,6 +36,7 @@ static const ldap_extra_t ldap_extra = { ldap_back_proxy_authz_ctrl, ldap_back_controls_free, slap_idassert_authzfrom_parse_cf, + slap_idassert_passthru_parse_cf, slap_idassert_parse_cf, slap_retry_info_destroy, slap_retry_info_parse, diff --git a/servers/slapd/back-ldap/proto-ldap.h b/servers/slapd/back-ldap/proto-ldap.h index bdf6399047..2c4ef6c2bd 100644 --- a/servers/slapd/back-ldap/proto-ldap.h +++ b/servers/slapd/back-ldap/proto-ldap.h @@ -102,6 +102,7 @@ extern int slap_retry_info_parse( char *in, slap_retry_info_t *ri, extern int slap_retry_info_unparse( slap_retry_info_t *ri, struct berval *bvout ); extern int slap_idassert_authzfrom_parse_cf( const char *fname, int lineno, const char *arg, slap_idassert_t *si ); +extern int slap_idassert_passthru_parse_cf( const char *fname, int lineno, const char *arg, slap_idassert_t *si ); extern int slap_idassert_parse_cf( const char *fname, int lineno, int argc, char *argv[], slap_idassert_t *si ); extern int chain_initialize( void ); -- 2.39.5