From: Bradley Nicholes Date: Fri, 23 Sep 2005 14:20:22 +0000 (+0000) Subject: mod_ldap: Fix PR 36563. Keep track of the number of attributes retrieved from LDAP... X-Git-Tag: 2.0.55~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a4536842d5b33a3193f4fe4a350612baa1471273;p=thirdparty%2Fapache%2Fhttpd.git mod_ldap: Fix PR 36563. Keep track of the number of attributes retrieved from LDAP so that all of the values can be properly cached even if the value is NULL. Reviewed by: bnicholes, minfrin, jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.0.x@291123 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 16fc6c14dd9..edc793ef06e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,11 @@ -*- coding: utf-8 -*- Changes with Apache 2.0.55 + *) mod_ldap: Fix PR 36563. Keep track of the number of attributes + retrieved from LDAP so that all of the values can be properly + cached even if the value is NULL. + [Brad Nicholes, Ondrej Sury ] + *) SECURITY: CAN-2005-2491 (cve.mitre.org): Fix integer overflows in PCRE in quantifier parsing which could be triggered by a local user through use of a carefully-crafted diff --git a/STATUS b/STATUS index 66cafc08fd8..2d93e2681b0 100644 --- a/STATUS +++ b/STATUS @@ -266,14 +266,6 @@ PATCHES PROPOSED TO BACKPORT FROM TRUNK: algorithims can be pretty "interesting", probably more 2.2. - *) mod_ldap: Fix PR 36563. Keep track of the number of attributes - retrieved from LDAP so that all of the values can be properly - cached even if the value is NULL. - http://issues.apache.org/bugzilla/attachment.cgi?id=16429 - or - http://svn.apache.org/viewcvs.cgi?rev=156587&view=rev - +1: bnicholes, minfrin, jim - PATCHES TO BACKPORT THAT ARE ON HOLD OR NOT GOING ANYWHERE SOON: *) Replace some of the mutex locking in the worker MPM with diff --git a/modules/experimental/util_ldap.c b/modules/experimental/util_ldap.c index 9a744457844..dabc4e7dec7 100644 --- a/modules/experimental/util_ldap.c +++ b/modules/experimental/util_ldap.c @@ -769,6 +769,7 @@ LDAP_DECLARE(int) util_ldap_cache_checkuserid(request_rec *r, util_ldap_connecti const char ***retvals) { const char **vals = NULL; + int numvals = 0; int result = 0; LDAPMessage *res, *entry; char *dn; @@ -932,6 +933,7 @@ start_over: int i = 0; while (attrs[k++]); vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1)); + numvals = k; while (attrs[i]) { char **values; int j = 0; @@ -959,6 +961,7 @@ start_over: the_search_node.bindpw = bindpw; the_search_node.lastbind = apr_time_now(); the_search_node.vals = vals; + the_search_node.numvals = numvals; /* Search again to make sure that another thread didn't ready insert this node into the cache before we got here. If it does exist then update the lastbind */ @@ -1001,6 +1004,7 @@ LDAP_DECLARE(int) util_ldap_cache_getuserdn(request_rec *r, util_ldap_connection const char ***retvals) { const char **vals = NULL; + int numvals = 0; int result = 0; LDAPMessage *res, *entry; char *dn; @@ -1115,6 +1119,7 @@ start_over: int i = 0; while (attrs[k++]); vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1)); + numvals = k; while (attrs[i]) { char **values; int j = 0; @@ -1142,6 +1147,7 @@ start_over: the_search_node.bindpw = NULL; the_search_node.lastbind = apr_time_now(); the_search_node.vals = vals; + the_search_node.numvals = numvals; /* Search again to make sure that another thread didn't ready insert this node into the cache before we got here. If it does exist then update the lastbind */ diff --git a/modules/experimental/util_ldap_cache.c b/modules/experimental/util_ldap_cache.c index ca856890772..58b3c6fbfed 100644 --- a/modules/experimental/util_ldap_cache.c +++ b/modules/experimental/util_ldap_cache.c @@ -158,18 +158,22 @@ void *util_ldap_search_node_copy(util_ald_cache_t *cache, void *c) /* copy vals */ if (node->vals) { - int k = 0; + int k = node->numvals; int i = 0; - while (node->vals[k++]); if (!(newnode->vals = util_ald_alloc(cache, sizeof(char *) * (k+1)))) { util_ldap_search_node_free(cache, newnode); return NULL; } - while (node->vals[i]) { - if (!(newnode->vals[i] = util_ald_strdup(cache, node->vals[i]))) { - util_ldap_search_node_free(cache, newnode); - return NULL; + newnode->numvals = node->numvals; + for (;k;k--) { + if (node->vals[i]) { + if (!(newnode->vals[i] = util_ald_strdup(cache, node->vals[i]))) { + util_ldap_search_node_free(cache, newnode); + return NULL; + } } + else + newnode->vals[i] = NULL; i++; } } @@ -199,9 +203,13 @@ void util_ldap_search_node_free(util_ald_cache_t *cache, void *n) { int i = 0; util_search_node_t *node = (util_search_node_t *)n; + int k = node->numvals; + if (node->vals) { - while (node->vals[i]) { - util_ald_free(cache, node->vals[i++]); + for (;k;k--,i++) { + if (node->vals[i]) { + util_ald_free(cache, node->vals[i]); + } } util_ald_free(cache, node->vals); } diff --git a/modules/experimental/util_ldap_cache.h b/modules/experimental/util_ldap_cache.h index 5a0ab79f334..51e50a51d20 100644 --- a/modules/experimental/util_ldap_cache.h +++ b/modules/experimental/util_ldap_cache.h @@ -110,6 +110,7 @@ typedef struct util_search_node_t { NULL if the bind failed */ apr_time_t lastbind; /* Time of last successful bind */ const char **vals; /* Values of queried attributes */ + int numvals; /* Number of queried attributes */ } util_search_node_t; /*