From 8bbe3542ebf48c6dd4864c0614f35f29d2a8076c Mon Sep 17 00:00:00 2001 From: William Brown Date: Fri, 10 Nov 2017 11:21:30 +1000 Subject: [PATCH] Ticket 49445 - Memory leak in ldif2db Bug Description: Memory leak in ldif2db of the instance name selected for the import Fix Description: Free the affected memory. Update the test case to work on python 3 https://pagure.io/389-ds-base/issue/49445 Author: wibrown Review by: ??? --- .../mapping_tree/referral_during_tot_init.py | 57 -------------------- .../mapping_tree/referral_during_tot_init_test.py | 62 ++++++++++++++++++++++ ldap/servers/slapd/main.c | 16 +++--- src/lib389/lib389/dbgen.py | 10 ++++ 4 files changed, 81 insertions(+), 64 deletions(-) delete mode 100644 dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py create mode 100644 dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init_test.py diff --git a/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py b/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py deleted file mode 100644 index e5aee7d..0000000 --- a/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init.py +++ /dev/null @@ -1,57 +0,0 @@ -# --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2017 Red Hat, Inc. -# All rights reserved. -# -# License: GPL (version 3 or any later version). -# See LICENSE for details. -# --- END COPYRIGHT BLOCK --- -# -import ldap -import pytest -from lib389.topologies import topology_m2 -from lib389._constants import (DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2, TASK_WAIT) - -from lib389.idm.user import (TEST_USER_PROPERTIES, UserAccounts) - -def test_referral_during_tot(topology_m2): - - master1 = topology_m2.ms["master1"] - master2 = topology_m2.ms["master2"] - - # Create a bunch of entries on master1 - ldif_dir = master1.get_ldif_dir() - import_ldif = ldif_dir + '/ref_during_tot_import.ldif' - master1.buildLDIF(10000, import_ldif) - - master1.stop() - try: - master1.ldif2db(bename=None, excludeSuffixes=None, encrypt=False, suffixes=[DEFAULT_SUFFIX], import_file=import_ldif) - except: - pass - # master1.tasks.importLDIF(suffix=DEFAULT_SUFFIX, input_file=import_ldif, args={TASK_WAIT: True}) - master1.start() - users = UserAccounts(master1, DEFAULT_SUFFIX, rdn='ou=Accounting') - - u = users.create(properties=TEST_USER_PROPERTIES) - u.set('userPassword', 'password') - - binddn = u.dn - bindpw = 'password' - - # Now export them to master2 - master1.agreement.init(DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2) - - # While that's happening try to bind as a user to master 2 - # This should trigger the referral code. - for i in range(0, 100): - conn = ldap.initialize(master2.toLDAPURL()) - conn.set_option(ldap.OPT_REFERRALS, False) - try: - conn.simple_bind_s(binddn, bindpw) - conn.unbind_s() - except ldap.REFERRAL: - pass - - # Done. - - diff --git a/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init_test.py b/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init_test.py new file mode 100644 index 0000000..d7529f4 --- /dev/null +++ b/dirsrvtests/tests/suites/mapping_tree/referral_during_tot_init_test.py @@ -0,0 +1,62 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2017 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# +import ldap +import pytest +from lib389.topologies import topology_m2 +from lib389._constants import (DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2, TASK_WAIT) + +from lib389.idm.user import (TEST_USER_PROPERTIES, UserAccounts) + +from lib389.dbgen import dbgen + +def test_referral_during_tot(topology_m2): + + master1 = topology_m2.ms["master1"] + master2 = topology_m2.ms["master2"] + + users = UserAccounts(master2, DEFAULT_SUFFIX) + + u = users.create(properties=TEST_USER_PROPERTIES) + u.set('userPassword', 'password') + + binddn = u.dn + bindpw = 'password' + + # Create a bunch of entries on master1 + ldif_dir = master1.get_ldif_dir() + import_ldif = ldif_dir + '/ref_during_tot_import.ldif' + dbgen(master1, 10000, import_ldif, DEFAULT_SUFFIX) + + master1.stop() + master1.ldif2db(bename=None, excludeSuffixes=None, encrypt=False, suffixes=[DEFAULT_SUFFIX], import_file=import_ldif) + master1.start() + # Recreate the user on m1 also, so that if the init finishes first ew don't lose the user on m2 + users = UserAccounts(master1, DEFAULT_SUFFIX) + u = users.create(properties=TEST_USER_PROPERTIES) + u.set('userPassword', 'password') + # Now export them to master2 + master1.agreement.init(DEFAULT_SUFFIX, HOST_MASTER_2, PORT_MASTER_2) + + # While that's happening try to bind as a user to master 2 + # This should trigger the referral code. + count = 0 + for i in range(0, 100): + conn = ldap.initialize(master2.toLDAPURL()) + conn.set_option(ldap.OPT_REFERRALS, False) + try: + conn.simple_bind_s(binddn, bindpw) + conn.unbind_s() + except ldap.REFERRAL: + count = count + 1 + # Means we never go a referral, should not happen! + assert count > 0 + + # Done. + + diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c index f8b591e..d5f943a 100644 --- a/ldap/servers/slapd/main.c +++ b/ldap/servers/slapd/main.c @@ -2051,11 +2051,11 @@ slapd_exemode_ldif2db(struct main_config *mcfg) * otherwise, we use included/excluded suffix list to specify a backend. */ if (NULL == mcfg->cmd_line_instance_name) { - char **instances, **ip; + char **instances; + char **ip; int counter; - if (lookup_instance_name_by_suffixes(mcfg->db2ldif_include, mcfg->db2ldif_exclude, - &instances) < 0) { + if (lookup_instance_name_by_suffixes(mcfg->db2ldif_include, mcfg->db2ldif_exclude, &instances) < 0) { slapi_log_err(SLAPI_LOG_ERR, "slapd_exemode_ldif2db", "Backend instances name [-n ] or " "included suffix [-s ] need to be specified.\n"); @@ -2082,6 +2082,7 @@ slapd_exemode_ldif2db(struct main_config *mcfg) slapi_log_err(SLAPI_LOG_INFO, "slapd_exemode_ldif2db", "Backend Instance: %s\n", *instances); mcfg->cmd_line_instance_name = *instances; + slapi_ch_free((void **)&instances); } } else { slapi_log_err(SLAPI_LOG_ERR, "slapd_exemode_ldif2db", @@ -2146,6 +2147,7 @@ slapd_exemode_ldif2db(struct main_config *mcfg) } slapi_pblock_destroy(pb); slapi_ch_free((void **)&(mcfg->myname)); + slapi_ch_free((void **)&(mcfg->cmd_line_instance_name)); charray_free(mcfg->cmd_line_instance_names); charray_free(mcfg->db2ldif_include); charray_free(mcfg->db2index_attrs); @@ -2174,8 +2176,7 @@ slapd_exemode_db2ldif(int argc, char **argv, struct main_config *mcfg) char **instances, **ip; int counter; - if (lookup_instance_name_by_suffixes(mcfg->db2ldif_include, mcfg->db2ldif_exclude, - &instances) < 0) { + if (lookup_instance_name_by_suffixes(mcfg->db2ldif_include, mcfg->db2ldif_exclude, &instances) < 0) { slapi_log_err(SLAPI_LOG_ERR, "slapd_exemode_db2ldif", "Backend instances name [-n ] or " "included suffix [-s ] need to be specified.\n"); @@ -2388,8 +2389,7 @@ slapd_exemode_db2index(struct main_config *mcfg) char **instances, **ip; int counter; - if (lookup_instance_name_by_suffixes(mcfg->db2ldif_include, mcfg->db2ldif_exclude, - &instances) < 0) { + if (lookup_instance_name_by_suffixes(mcfg->db2ldif_include, mcfg->db2ldif_exclude, &instances) < 0) { slapi_log_err(SLAPI_LOG_ERR, "slapd_exemode_db2index", "Backend instances name [-n ] or " "included suffix [-s ] need to be specified.\n"); @@ -2416,6 +2416,7 @@ slapd_exemode_db2index(struct main_config *mcfg) slapi_log_err(SLAPI_LOG_INFO, "slapd_exemode_db2index", "Backend Instance: %s\n", *instances); mcfg->cmd_line_instance_name = *instances; + slapi_ch_free((void **)&instances); } } else { slapi_log_err(SLAPI_LOG_ERR, "slapd_exemode_db2index", @@ -2456,6 +2457,7 @@ slapd_exemode_db2index(struct main_config *mcfg) slapi_pblock_destroy(pb); slapi_ch_free((void **)&(mcfg->myname)); + slapi_ch_free((void **)&(mcfg->cmd_line_instance_name)); return (return_value); } diff --git a/src/lib389/lib389/dbgen.py b/src/lib389/lib389/dbgen.py index a0cda94..447c697 100644 --- a/src/lib389/lib389/dbgen.py +++ b/src/lib389/lib389/dbgen.py @@ -143,6 +143,16 @@ objectClass: top objectClass: organizationalUnit ou: Payroll +dn: ou=People,{SUFFIX} +objectClass: top +objectClass: organizationalUnit +ou: People + +dn: ou=Groups,{SUFFIX} +objectClass: top +objectClass: organizationalUnit +ou: Groups + """ def dbgen(instance, number, ldif_file, suffix): -- 1.8.3.1