Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4860392

InitialDirContext() leaves LDAP connection open when there is Error 49.

    XMLWordPrintable

Details

    Description

      This problem is reproduceable a 100% of the time.
      Here are the requirements.
      Client OS: Linux only. Does not happen on Solaris.
      Directory Server: SunONE Directory server. Same failure seen with
      many other directory servers as well.
      JAVA Version: 1.3.1_08 not seen on 1.4.1_02.

      Execute the following code. Provide correct login and password for the previledged users "cn=Directory Manager" but provide wrong password of the
      normal user.

      import javax.naming.directory.*;
      import javax.naming.*;
      import java.util.Hashtable;


      class Tester{
       public static void main(String[] args){
              Tester t=new Tester();
              t.doTest("ldap://my-system.East.Sun.COM:389/",
                      "ou=People,o=isp", "cn=Directory Manager", "password", "uid", "TUser", "wrongpass");
              try{
                      Thread.sleep(10000);
              } catch (Exception e){}
       }
       public void doTest( String ldapUrl, String searchContext, String privilegedUserDN, String privilegedUserPwd, String userTag, String userId, String userPasswd )
          {
            boolean initialBindSucceeded = false;
            boolean userFound = false;
            boolean userBindSucceeded = false;
            DirContext initialCtx = null;
            NamingEnumeration searchResults = null;
            DirContext userCtx = null;

            // Create initial directory Context
            Hashtable env = new Hashtable(10);
            env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
            env.put(Context.PROVIDER_URL, ldapUrl);
            env.put(Context.SECURITY_AUTHENTICATION, "simple");
            env.put(Context.SECURITY_PRINCIPAL, privilegedUserDN);
            env.put(Context.SECURITY_CREDENTIALS, privilegedUserPwd);
            env.put("java.naming.ldap.derefAliases" , "never");
            env.put(Context.REFERRAL, "ignore");
            env.put("java.naming.ldap.referral.limit", "0");

            try
            {
              // Bind using privileged user credentials
              initialCtx = new InitialDirContext( env );
              initialBindSucceeded = initialCtx != null;
              if ( initialBindSucceeded )
                System.out.println( "Initial bind succeeded." );
              // Search for user w/ username from login form
              String strSearchFilter = "(" + userTag + "=" + userId + ")";
              SearchResult sr = null;
              String srDN = null;
              SearchControls searchCtls = new SearchControls();
              boolean bSubtree = true;
              searchCtls.setSearchScope( bSubtree ? SearchControls.SUBTREE_SCOPE : SearchControls.ONELEVEL_SCOPE );
              searchResults = initialCtx.search(searchContext, strSearchFilter, search
      Ctls);
              userFound = searchResults.hasMore() && (sr=(SearchResult)searchResults.next()) != null;
              if ( userFound )
              {
                srDN = sr.getName() + "," + searchContext;
                System.out.println( "User found." );
                System.out.println( "Search result DN: " + srDN );
              }
              else
              {
                throw new RuntimeException( "User not found." );
              }

              // Bind using login form credentials
              env.remove(Context.SECURITY_PRINCIPAL);
              env.remove(Context.SECURITY_CREDENTIALS);
              env.put(Context.SECURITY_PRINCIPAL, srDN);
              env.put(Context.SECURITY_CREDENTIALS, userPasswd);
              userCtx = new InitialDirContext( env );
              userBindSucceeded = userCtx != null;
              if ( userBindSucceeded )
                System.out.println( "User bind succeeded." );
              Thread.sleep(10000);
           }
           catch( Exception e )
           {
             if ( !initialBindSucceeded )
               System.out.println( "Initial bind failed: " + e.getMessage() );
             if ( !userFound )
               System.out.println( "User not found: " + e.getMessage() );
             if ( !userBindSucceeded )
               System.out.println( "User bind failed: " + e.getMessage() );
             e.printStackTrace( System.out );
           }
           finally
           {
             System.out.println( "Closing resources...");
             try
             {
               if ( searchResults != null )
                 searchResults.close();
               if ( initialCtx != null )
                 initialCtx.close();
               if ( userCtx != null )
                 userCtx.close();
             }
             catch( NamingException ne )
             {
               System.out.println( "Error trying to close LDAP connection: " + ne.getMessage() );
               ne.printStackTrace( System.out );
             }
           }
         }
      }

      After you run the code you will see that the second connection is still in
      the ESTABLISHED state. This is because the InitialDirContext() returned null
      but still kept the connection open. In this case there is no way to close the
      connection.

      Attachments

        Activity

          People

            Unassigned Unassigned
            arajadur Angelo Rajadurai
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: