LDAP connection leak in this code

Can someone explain to me why this piece of code accidentally consoles LDAP connections? I see that the number of established TCP / IP connections grows over time, and at some point this starts to cause problems. I tried to tinker with the properties of the com.sun.jndi.ldap.connect environment (turning on the pool, disconnecting it, etc.), but it did not seem to help.

This means that my lame part of the code has errors. How to do this generally better and make sure that I never "console" LDAP connections?

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class LdapUtil {
    private String ldap_context = "ou=myunit,dc=com";
    protected static String ldap_server = "ldap://ldapserver:389/";
    private String ldap_prefix = "(&(uid=";
    private String ldap_postfix = ")(objectclass=inetOrgPerson))";
    private String[] ldap_attributes = {"uid","departmentNumber","cn","postOfficeBox","mail"};
    private Properties ldap_properties;
    private SearchControls ldap_searchcontrols;
        private static String ldap_principal = "uid=bind_account,cn=users,ou=myunit,dc=com";
        private static String ldap_credentials = "qwerty";

    private List<String> getUserAttributes(final String userId) {
        List<String> UserAttributes = new ArrayList<String>();
        InitialDirContext ctx = null;
        NamingEnumeration<SearchResult> resultsEnum = null;
        NamingEnumeration<String> atrEnum = null;

        // Connect the LDAP
        try {
        ctx = new InitialDirContext(this.ldap_properties);
        // Prepare the query string
        String query = this.ldap_prefix+ userId+ this.ldap_postfix;
        // Query!
        resultsEnum = ctx.search(this.ldap_context, query, this.ldap_searchcontrols);

        // Enumerate the results
        while (resultsEnum.hasMore()) {
            SearchResult sr = (SearchResult) resultsEnum.nextElement();

            // Get all the attributes for a hit
            Attributes atr = sr.getAttributes();
            // Enumerate the attributes
            atrEnum = atr.getIDs();

            while (atrEnum.hasMore()) {
                    String nextid = atrEnum.nextElement();
                    String nextattribute = atr.get(nextid).toString();
                    UserAttributes.add(nextattribute);
            }

        }
        } catch ( Exception eom ) {
            System.out.println("LDAP exception");
        } finally {
            try {
                if (atrEnum!=null)
                atrEnum.close();
                if (resultsEnum!=null)
                resultsEnum.close();
                if (ctx!=null)
                ctx.close();
            } catch (NamingException eo) {
                // nothing
            } catch (NullPointerException eo) {
                // Nothing
            }
        } 
        return UserAttributes;
    }


    /*
     * Parses the LDAP search results and searches for selected attribute.
     */
    private String getAttribute (final List<String> attributes,final String attribuutti) {
        String result = null;
        // Let go through all attributes
        for (int i = 0; i < attributes.size(); i++) {
            String attribute = attributes.get(i).toString();
            // Look for match
            if (attribute.startsWith(attribuutti)) {
                // Return the value after the space
                int k = attribute.indexOf(" ");
                result = attribute.substring(k+1,attribute.length());
            }
        }
        return result;
    }


    public LdapUtil(String remoteuser) {

        // Pre-initialize LDAP connection related properties
        this.ldap_properties = new Properties();
        this.ldap_properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        this.ldap_properties.put(Context.PROVIDER_URL, ldap_server) ;
        this.ldap_properties.put(Context.REFERRAL, "follow" );
        this.ldap_properties.put(Context.SECURITY_AUTHENTICATION, "simple");
        this.ldap_properties.put(Context.SECURITY_PRINCIPAL,ldap_principal);
        this.ldap_properties.put(Context.SECURITY_CREDENTIALS,ldap_credentials);
        this.ldap_properties.put("com.sun.jndi.ldap.read.timeout", "10000");
        this.ldap_properties.put("com.sun.jndi.ldap.connect.timeout", "10000");
        // Tried with both pooling and without - doesn't solve problems
        this.ldap_properties.put("com.sun.jndi.ldap.connect.pool", "false");

        // Pre-initialize LDAP search controls
        this.ldap_searchcontrols = new SearchControls();
        this.ldap_searchcontrols.setSearchScope(SearchControls.SUBTREE_SCOPE);
        this.ldap_searchcontrols.setReturningAttributes(this.ldap_attributes);

            // The List for attributes
        List<String> attributes = null;

        attributes = getUserAttributes(remoteuser);
    }

}
+3
source share
3 answers

, finally . Ff close , close . :

final Res res = acquire();
try {
    use(res);
} finally {
    res.release();
}

, try-finally.

( Sun JRE, LDAP ( Kerberos) . "SunSolve" )

+3
} finally {
    try {
        if (atrEnum!=null)
        atrEnum.close();
        if (resultsEnum!=null)
        resultsEnum.close();
        if (ctx!=null)
        ctx.close();
    } catch (NamingException eo) {
        // nothing
    } catch (NullPointerException eo) {
        // Nothing
    }
}

atrEnum.close() , resultsEnum ctx .

, close() try/catch.

} finally {
    if (atrEnum != null) try { 
        atrEnum.close(); 
    } catch (NamingException logOrIgnore) {}
    if (resultsEnum != null) try {
        resultsEnum.close();
    } catch (NamingException logOrIgnore) {}
    if (ctx != null) try {
        ctx.close();
    } catch (NamingException logOrIgnore) {}
}
+4

. :

private void closeResources(final InitialDirContext ctx,final NamingEnumeration<SearchResult> resultsEnum,final NamingEnumeration<String> atrEnum) {
    try {
        atrEnum.close();
    } catch (Exception eom) {}

    try {
        resultsEnum.close();
    } catch (Exception eom) {}

    try {
        ctx.close();
    } catch (Exception eom) {}
}

finally . , .

0

Source: https://habr.com/ru/post/1732225/


All Articles