]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#10247 libldap: add ldap_url_check_ext() to check URL extensions
authorHoward Chu <hyc@openldap.org>
Tue, 6 Aug 2024 16:52:11 +0000 (17:52 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Tue, 20 Aug 2024 15:39:04 +0000 (15:39 +0000)
And check validity earlier, in ldap_initialize() and ldap_init_fd().

include/ldap_pvt.h
libraries/libldap/open.c
libraries/libldap/request.c
libraries/libldap/url.c

index 431f71eebf2f4fc80d921f2d6aa886817bfa1029..13aefe1d706f584046f99c7818f8e60629125eb1 100644 (file)
@@ -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 ));
 
index 58457c0c0afe0f537c769ea8a2079e38ad129b8d..6dad331ecd0241c2f44b2d4e02d08e7975270b7a 100644 (file)
@@ -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 );
index 5ed10e9a22420b29be53a68dfc0e143480571a86..6bc22a65b25a652b46a95428f7b4ed0d7ea24eef 100644 (file)
@@ -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 */
index 685304549b78a9cfd2a37b40bed8f5e701077fbb..3c210eae304c797409f58f1133542e6f157de400 100644 (file)
@@ -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 )
 {