From 0500576056f1a36022e598d38ad59abc63d64c94 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 8 Apr 2006 11:12:30 +0000 Subject: [PATCH] add support for old proxyAuthz encoding; allow to workaround buggy implementations of the new version (now RFC4370) --- servers/slapd/back-ldap/back-ldap.h | 10 ++-- servers/slapd/back-ldap/bind.c | 80 +++++++++++++++++++++++++++++ servers/slapd/back-ldap/config.c | 53 ++++++++++++++++++- 3 files changed, 138 insertions(+), 5 deletions(-) diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 8a19a72c05..3fb58ba581 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -152,10 +152,12 @@ typedef struct ldapinfo_t { #define li_idassert_secprops li_idassert.sb_secprops unsigned li_idassert_flags; -#define LDAP_BACK_AUTH_NONE 0x00U -#define LDAP_BACK_AUTH_NATIVE_AUTHZ 0x01U -#define LDAP_BACK_AUTH_OVERRIDE 0x02U -#define LDAP_BACK_AUTH_PRESCRIPTIVE 0x04U +#define LDAP_BACK_AUTH_NONE 0x00U +#define LDAP_BACK_AUTH_NATIVE_AUTHZ 0x01U +#define LDAP_BACK_AUTH_OVERRIDE 0x02U +#define LDAP_BACK_AUTH_PRESCRIPTIVE 0x04U +#define LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ 0x08U +#define LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND 0x10U BerVarray li_idassert_authz; /* end of ID assert stuff */ diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index 5ce7c02058..2242a6d23f 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -1616,6 +1616,86 @@ ldap_back_proxy_authz_ctrl( break; } + /* Older versions of required + * to encode the value of the authzID (and called it proxyDN); + * this hack provides compatibility with those DSAs that + * implement it this way */ + if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) { + struct berval authzID = ctrls[ 0 ]->ldctl_value; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + ber_tag_t tag; + + ber_init2( ber, 0, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); + + tag = ber_printf( ber, "O", &authzID ); + if ( tag == LBER_ERROR ) { + rs->sr_err = LDAP_OTHER; + goto free_ber; + } + + if ( ber_flatten2( ber, &ctrls[ 0 ]->ldctl_value, 1 ) == -1 ) { + rs->sr_err = LDAP_OTHER; + goto free_ber; + } + +free_ber:; + op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx ); + ber_free_buf( ber ); + + if ( rs->sr_err != LDAP_SUCCESS ) { + op->o_tmpfree( ctrls, op->o_tmpmemctx ); + ctrls = NULL; + } + + } else if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) { + struct berval authzID = ctrls[ 0 ]->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 ); + rs->sr_err = LDAP_PROTOCOL_ERROR; + goto done; + } + + tmp = authzID; + tmp.bv_val += STRLENOF( "dn:" ); + tmp.bv_len -= STRLENOF( "dn:" ); + + ber_init2( ber, 0, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); + + /* apparently, Mozilla API encodes this + * as "SEQUENCE { LDAPDN }" */ + tag = ber_printf( ber, "{O}", &tmp ); + if ( tag == LBER_ERROR ) { + rs->sr_err = LDAP_OTHER; + goto free_ber2; + } + + if ( ber_flatten2( ber, &ctrls[ 0 ]->ldctl_value, 1 ) == -1 ) { + rs->sr_err = LDAP_OTHER; + goto free_ber2; + } + +free_ber2:; + op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx ); + 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; + } + if ( op->o_ctrls ) { for ( i = 0; op->o_ctrls[ i ]; i++ ) { ctrls[ i + 1 ] = op->o_ctrls[ i ]; diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 8462ad7746..ed5097518c 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -453,7 +453,7 @@ ldap_back_cf_gen( ConfigArgs *c ) (void)lutil_strcopy( ptr, "authz=native" ); } - len = bv.bv_len + STRLENOF( "flags=non-prescriptive,override" ); + len = bv.bv_len + STRLENOF( "flags=non-prescriptive,override,obsolete-encoding-workaround" ); /* flags */ if ( !BER_BVISEMPTY( &bv ) ) { len += STRLENOF( " " ); @@ -479,6 +479,13 @@ ldap_back_cf_gen( ConfigArgs *c ) ptr = lutil_strcopy( ptr, ",override" ); } + if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) { + ptr = lutil_strcopy( ptr, ",obsolete-proxy-authz" ); + + } else if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) { + ptr = lutil_strcopy( ptr, ",obsolete-encoding-workaround" ); + } + bv.bv_len = ( ptr - bv.bv_val ); /* end-of-flags */ } @@ -967,6 +974,28 @@ done_url:; } else if ( strcasecmp( c->argv[ i ], "non-prescriptive" ) == 0 ) { li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE ); + } else if ( strcasecmp( c->argv[ i ], "obsolete-proxy-authz" ) == 0 ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: \"obsolete-proxy-authz\" flag " + "in \"idassert-mode \" " + "incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n", + c->fname, c->lineno, 0 ); + return 1; + } + li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ; + + } else if ( strcasecmp( c->argv[ i ], "obsolete-encoding-workaround" ) == 0 ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: \"obsolete-encoding-workaround\" flag " + "in \"idassert-mode \" " + "incompatible with previously issued \"obsolete-proxy-authz\" flag.\n", + c->fname, c->lineno, 0 ); + return 1; + } + li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND; + } else { Debug( LDAP_DEBUG_ANY, "%s: line %d: unknown flag #%d " @@ -1125,6 +1154,28 @@ done_url:; } else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) { li->li_idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE ); + } else if ( strcasecmp( flags[ j ], "obsolete-proxy-authz" ) == 0 ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: \"obsolete-proxy-authz\" flag " + "in \"idassert-mode \" " + "incompatible with previously issued \"obsolete-encoding-workaround\" flag.\n", + c->fname, c->lineno, 0 ); + return 1; + } + li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ; + + } else if ( strcasecmp( flags[ j ], "obsolete-encoding-workaround" ) == 0 ) { + if ( li->li_idassert_flags & LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ ) { + Debug( LDAP_DEBUG_ANY, + "%s: line %d: \"obsolete-encoding-workaround\" flag " + "in \"idassert-mode \" " + "incompatible with previously issued \"obsolete-proxy-authz\" flag.\n", + c->fname, c->lineno, 0 ); + return 1; + } + li->li_idassert_flags |= LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND; + } else { snprintf( c->msg, sizeof( c->msg ), "\"idassert-bind \": " -- 2.39.5