KDC denial of service attacks [MITKRB5-SA-2011-002 CVE-2011-0281 CVE-2011-0282]
authorTom Yu <tlyu@mit.edu>
Wed, 9 Feb 2011 21:38:08 +0000 (21:38 +0000)
committerTom Yu <tlyu@mit.edu>
Wed, 9 Feb 2011 21:38:08 +0000 (21:38 +0000)
pull up r24622 from trunk, except for the fix for CVE-2011-0283, which
only applies to krb5-1.9.

 ------------------------------------------------------------------------
 r24622 | tlyu | 2011-02-09 15:25:08 -0500 (Wed, 09 Feb 2011) | 10 lines

 ticket: 6860
 subject: KDC denial of service attacks [MITKRB5-SA-2011-002 CVE-2011-0281 CVE-2011-0282 CVE-2011-0283]
 tags: pullup
 target_version: 1.9.1

 [CVE-2011-0281 CVE-2011-0282] Fix some LDAP back end principal name
 handling that could cause the KDC to hang or crash.

 [CVE-2011-0283] Fix a KDC null pointer dereference introduced in krb5-1.9.

ticket: 6865
version_fixed: 1.7.2
status: resolved

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/krb5-1-7@24628 dc483132-0cff-0310-8789-dd5450dbe970

src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap.h
src/plugins/kdb/ldap/libkdb_ldap/kdb_ldap_conn.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c

index 802ab0fc36ae3611ef1b6fb5def329a0903a8631..a214b85c2a4af984e2d62e68310d23c6fb98d1ec 100644 (file)
@@ -101,14 +101,18 @@ extern void prepend_err_str (krb5_context ctx, const char *s, krb5_error_code er
 #define LDAP_SEARCH(base, scope, filter, attrs)   LDAP_SEARCH_1(base, scope, filter, attrs, CHECK_STATUS)
 
 #define LDAP_SEARCH_1(base, scope, filter, attrs, status_check)        \
-      do { \
-         st = ldap_search_ext_s(ld, base, scope, filter, attrs, 0, NULL, NULL, &timelimit, LDAP_NO_LIMIT, &result); \
-         if (translate_ldap_error(st, OP_SEARCH) == KRB5_KDB_ACCESS_ERROR) { \
-              tempst = krb5_ldap_rebind(ldap_context, &ldap_server_handle); \
-             if (ldap_server_handle) \
-                 ld = ldap_server_handle->ldap_handle; \
-         } \
-      }while (translate_ldap_error(st, OP_SEARCH) == KRB5_KDB_ACCESS_ERROR && tempst == 0); \
+    tempst = 0;                                                                \
+    st = ldap_search_ext_s(ld, base, scope, filter, attrs, 0, NULL,    \
+                          NULL, &timelimit, LDAP_NO_LIMIT, &result);   \
+    if (translate_ldap_error(st, OP_SEARCH) == KRB5_KDB_ACCESS_ERROR) { \
+       tempst = krb5_ldap_rebind(ldap_context, &ldap_server_handle);   \
+       if (ldap_server_handle)                                         \
+           ld = ldap_server_handle->ldap_handle;                       \
+       if (tempst == 0)                                                \
+           st = ldap_search_ext_s(ld, base, scope, filter, attrs, 0,   \
+                                  NULL, NULL, &timelimit,              \
+                                  LDAP_NO_LIMIT, &result);             \
+    }                                                                  \
       \
       if (status_check != IGNORE_STATUS) { \
         if (tempst != 0) { \
index fdc5d10c771738116097bf94a3bbbcc0a93a24c3..2eb5894e4d3cd530819ccd1c394ac8455558179f 100644 (file)
@@ -296,6 +296,7 @@ krb5_ldap_rebind(ldap_context, ldap_server_handle)
 {
     krb5_ldap_server_handle     *handle = *ldap_server_handle;
 
+    ldap_unbind_ext_s(handle->ldap_handle, NULL, NULL);
     if ((ldap_initialize(&handle->ldap_handle, handle->server_info->server_name) != LDAP_SUCCESS)
        || (krb5_ldap_bind(ldap_context, handle) != LDAP_SUCCESS))
        return krb5_ldap_request_next_handle_from_pool(ldap_context, ldap_server_handle);
index 8625984d875beba77261c4a6e05255974ea5387d..28a93fd49bc552fcfd8d710289762bec5b8ca6d1 100644 (file)
@@ -449,12 +449,11 @@ is_principal_in_realm(ldap_context, searchfor)
      * portion, then the first portion of the principal name SHOULD be
      * "krbtgt".  All this check is done in the immediate block.
      */
-    if (searchfor->length == 2)
-       if ((strncasecmp(searchfor->data[0].data, "krbtgt",
-                        FIND_MAX(searchfor->data[0].length, strlen("krbtgt"))) == 0) &&
-           (strncasecmp(searchfor->data[1].data, defrealm,
-                        FIND_MAX(searchfor->data[1].length, defrealmlen)) == 0))
+    if (searchfor->length == 2) {
+       if (data_eq_string(searchfor->data[0], "krbtgt") &&
+           data_eq_string(searchfor->data[1], defrealm))
            return 0;
+    }
 
     /* first check the length, if they are not equal, then they are not same */
     if (strlen(defrealm) != searchfor->realm.length)
index 03c3da48d78b78ec23872394f38b29aae781d91a..34ca2f57acda6cfab76dd583e61ebc6fae9442ea 100644 (file)
@@ -106,10 +106,10 @@ krb5_ldap_get_principal(context, searchfor, flags, entries, nentries, more)
     int *nentries;             /* how much room/how many found */
     krb5_boolean *more;                /* are there more? */
 {
-    char                        *user=NULL, *filter=NULL, **subtree=NULL;
+    char                        *user=NULL, *filter=NULL, *filtuser=NULL;
     unsigned int                tree=0, ntrees=1, princlen=0;
     krb5_error_code            tempst=0, st=0;
-    char                        **values=NULL, *cname=NULL;
+    char                        **values=NULL, **subtree=NULL, *cname=NULL;
     LDAP                       *ld=NULL;
     LDAPMessage                        *result=NULL, *ent=NULL;
     krb5_ldap_context           *ldap_context=NULL;
@@ -145,12 +145,18 @@ krb5_ldap_get_principal(context, searchfor, flags, entries, nentries, more)
     if ((st=krb5_ldap_unparse_principal_name(user)) != 0)
        goto cleanup;
 
-    princlen = strlen(FILTER) + strlen(user) + 2 + 1;      /* 2 for closing brackets */
+    filtuser = ldap_filter_correct(user);
+    if (filtuser == NULL) {
+        st = ENOMEM;
+        goto cleanup;
+    }
+
+    princlen = strlen(FILTER) + strlen(filtuser) + 2 + 1;  /* 2 for closing brackets */
     if ((filter = malloc(princlen)) == NULL) {
        st = ENOMEM;
        goto cleanup;
     }
-    snprintf(filter, princlen, FILTER"%s))", user);
+    snprintf(filter, princlen, FILTER"%s))", filtuser);
 
     if ((st = krb5_get_subtree_info(ldap_context, &subtree, &ntrees)) != 0)
        goto cleanup;
@@ -234,6 +240,9 @@ cleanup:
     if (user)
        free(user);
 
+    if (filtuser)
+       free(filtuser);
+
     if (cname)
        free(cname);