From: Howard Chu Date: Tue, 6 Aug 2024 16:52:11 +0000 (+0100) Subject: ITS#10247 libldap: add ldap_url_check_ext() to check URL extensions X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c9ab732ec18e32c58643e44a45233a6ed87830b6;p=thirdparty%2Fopenldap.git ITS#10247 libldap: add ldap_url_check_ext() to check URL extensions And check validity earlier, in ldap_initialize() and ldap_init_fd(). --- diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h index 431f71eebf..13aefe1d70 100644 --- a/include/ldap_pvt.h +++ b/include/ldap_pvt.h @@ -67,6 +67,9 @@ LDAP_F (int) ldap_url_parselist_ext LDAP_P(( const char *sep, unsigned flags )); +LDAP_F (int) ldap_url_check_ext LDAP_P(( + struct ldap_url_desc *ludlist )); + LDAP_F (char *) ldap_url_list2urls LDAP_P(( struct ldap_url_desc *ludlist )); diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c index 58457c0c0a..6dad331ecd 100644 --- a/libraries/libldap/open.c +++ b/libraries/libldap/open.c @@ -308,6 +308,13 @@ ldap_initialize( LDAP **ldp, LDAP_CONST char *url ) ldap_ld_free(ld, 1, NULL, NULL); return rc; } + if ( ldap_url_check_ext( ld->ld_options.ldo_defludp )) { + rc = LDAP_NOT_SUPPORTED; + ld->ld_errno = rc; + ldap_ld_free(ld, 1, NULL, NULL); + return rc; + } + #ifdef LDAP_CONNECTIONLESS if (ldap_is_ldapc_url(url)) LDAP_IS_UDP(ld) = 1; @@ -344,6 +351,12 @@ ldap_init_fd( ldap_ld_free(ld, 1, NULL, NULL); return rc; } + if ( ldap_url_check_ext( ld->ld_options.ldo_defludp )) { + rc = LDAP_NOT_SUPPORTED; + ld->ld_errno = rc; + ldap_ld_free(ld, 1, NULL, NULL); + return rc; + } } LDAP_MUTEX_LOCK( &ld->ld_conn_mutex ); diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index 5ed10e9a22..6bc22a65b2 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -1167,19 +1167,12 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * goto done; } - if( srv->lud_crit_exts ) { - int ok = 0; -#ifdef HAVE_TLS - /* If StartTLS is the only critical ext, OK. */ - if ( find_tls_ext( srv ) == 2 && srv->lud_crit_exts == 1 ) - ok = 1; -#endif - if ( !ok ) { - /* we do not support any other extensions */ - ld->ld_errno = LDAP_NOT_SUPPORTED; - rc = -1; - goto done; - } + /* check for unrecognized critical extensions */ + if( srv->lud_crit_exts && + ( rc = ldap_url_check_ext( srv ))) { + ld->ld_errno = LDAP_NOT_SUPPORTED; + rc = -1; + goto done; } /* check connection for re-bind in progress */ diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c index 685304549b..3c210eae30 100644 --- a/libraries/libldap/url.c +++ b/libraries/libldap/url.c @@ -1211,6 +1211,62 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) return ldap_url_parse_ext( url_in, ludpp, LDAP_PVT_URL_PARSE_HISTORIC ); } +typedef struct lurl_critext { + struct berval oid; + struct berval names[2]; +} lurl_critext; + +lurl_critext lurl_extensions[] = { +#ifdef HAVE_TLS + {BER_BVC(LDAP_EXOP_START_TLS), {BER_BVC("StartTLS"), BER_BVC("X-StartTLS")}}, +#endif + {0, NULL} +}; + +/* return error if there are any unrecognized critical URL extensions */ +int +ldap_url_check_ext( LDAPURLDesc *ludp ) +{ + int i, j; + + for (; ludp; ludp=ludp->lud_next ) { + if ( !ludp->lud_crit_exts ) + continue; + + for ( i=0; ludp->lud_exts[i]; i++ ) + { + char *eq, *ext; + int ok = 0, n; + + ext = ludp->lud_exts[i]; + if ( ext[0] != '!' ) /* don't care about non-critical */ + continue; + ext++; + + eq = strchr( ext, '=' ); + if ( eq ) + n = eq - ext; + else + n = strlen( ext ); + + for ( j=0; lurl_extensions[j].oid.bv_len; j++ ) { + if (( n == lurl_extensions[j].oid.bv_len && + !strncmp( ext, lurl_extensions[j].oid.bv_val, n )) || + ( n == lurl_extensions[j].names[0].bv_len && + !strncasecmp( ext, lurl_extensions[j].names[0].bv_val, n )) || + ( n == lurl_extensions[j].names[1].bv_len && + !strncasecmp( ext, lurl_extensions[j].names[1].bv_val, n ))) { + ok = 1; + break; + } + } + if ( !ok ) + return LDAP_URL_ERR_BADEXTS; + } + } + return LDAP_URL_SUCCESS; +} + LDAPURLDesc * ldap_url_dup ( LDAPURLDesc *ludp ) {