From 778a5414b1148ea767020b5330b076fed666694f Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Fri, 25 Apr 2008 18:34:46 -0700 Subject: Fix bug 5419: memory leak in ads_do_search_all_args() when enumerating 1000s of entries The ads_do_search_all_args() function attempts to string together several LDAPMessage structures, returned across several paged ldap requests, into a single LDAPMessage structure. It does this by pulling entries off the second LDAPMessage structure and appending them to the first via the OpenLDAP specific ldap_add_result_entry() call. The problem with this approach is it skips non-entry messages such as the result, and controls. These messages are leaked. The short term solution as suggested by Volker is to replace the ads_*_entry() calls with ads_*_message() calls so we don't leak any messages. This fixes the leak but doesn't remove the dependence on the OpenLDAP specific implementation of ldap_add_result_entry(). (This used to be commit f1a5405409c396df394611e2a234522572d2860a) --- source3/libads/ldap.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'source3/libads/ldap.c') diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index b0f27b598b..9321302151 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -870,8 +870,8 @@ static ADS_STATUS ads_do_paged_search(ADS_STRUCT *ads, const char *bind_path, /* this relies on the way that ldap_add_result_entry() works internally. I hope that this works on all ldap libs, but I have only tested with openldap */ - for (msg = ads_first_entry(ads, res2); msg; msg = next) { - next = ads_next_entry(ads, msg); + for (msg = ads_first_message(ads, res2); msg; msg = next) { + next = ads_next_message(ads, msg); ldap_add_result_entry((LDAPMessage **)res, msg); } /* note that we do not free res2, as the memory is now @@ -2090,6 +2090,28 @@ int ads_count_replies(ADS_STRUCT *ads, void *res) return ldap_next_entry(ads->ldap.ld, res); } +/** + * pull the first message from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return first message from result + **/ + LDAPMessage *ads_first_message(ADS_STRUCT *ads, LDAPMessage *res) +{ + return ldap_first_message(ads->ldap.ld, res); +} + +/** + * pull the next message from a ADS result + * @param ads connection to ads server + * @param res Results of search + * @return next message from result + **/ + LDAPMessage *ads_next_message(ADS_STRUCT *ads, LDAPMessage *res) +{ + return ldap_next_message(ads->ldap.ld, res); +} + /** * pull a single string from a ADS result * @param ads connection to ads server -- cgit