/*
 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.jndi.ldap;

import java.io.*;
import java.util.Locale;
import java.util.Vector;
import java.util.Hashtable;

import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;

import com.sun.jndi.ldap.pool.PooledConnection;
import com.sun.jndi.ldap.pool.PoolCallback;
import com.sun.jndi.ldap.sasl.LdapSasl;
import com.sun.jndi.ldap.sasl.SaslInputStream;

/**
 * LDAP (RFC-1777) and LDAPv3 (RFC-2251) compliant client
 *
 * This class represents a connection to an LDAP client.
 * Callers interact with this class at an LDAP operation level.
 * That is, the caller invokes a method to do a SEARCH or MODRDN
 * operation and gets back the result.
 * The caller uses the constructor to create a connection to the server.
 * It then needs to use authenticate() to perform an LDAP BIND.
 * Note that for v3, BIND is optional so authenticate() might not
 * actually send a BIND. authenticate() can be used later on to issue
 * a BIND, for example, for a v3 client that wants to change the connection's
 * credentials.
 *<p>
 * Multiple LdapCtx might share the same LdapClient. For example, contexts
 * derived from the same initial context would share the same LdapClient
 * until changes to a context's properties necessitates its own LdapClient.
 * LdapClient methods that access shared data are thread-safe (i.e., caller
 * does not have to sync).
 *<p>
 * Fields:
 *   isLdapv3 - no sync; initialized and updated within sync authenticate();
 *       always updated when connection is "quiet" and not shared;
 *       read access from outside LdapClient not sync
 *   referenceCount - sync within LdapClient; exception is forceClose() which
 *       is used by Connection thread to close connection upon receiving
 *       an Unsolicited Notification.
 *       access from outside LdapClient must sync;
 *   conn - no sync; Connection takes care of its own sync
 *   unsolicited - sync Vector; multiple operations sync'ed
 *
 * @author Vincent Ryan
 * @author Jagane Sundar
 * @author Rosanna Lee
 */

public final class LdapClient implements PooledConnection {
    // ---------------------- Constants ----------------------------------
    private static final int debug = 0;
    static final boolean caseIgnore = true;

    // Default list of binary attributes
    private static final Hashtable<String, Boolean> defaultBinaryAttrs =
            new Hashtable<>(23,0.75f);
    static {
        defaultBinaryAttrs.put("userpassword", Boolean.TRUE);      //2.5.4.35
        defaultBinaryAttrs.put("javaserializeddata", Boolean.TRUE);
                                                //1.3.6.1.4.1.42.2.27.4.1.8
        defaultBinaryAttrs.put("javaserializedobject", Boolean.TRUE);
                                                // 1.3.6.1.4.1.42.2.27.4.1.2
        defaultBinaryAttrs.put("jpegphoto", Boolean.TRUE);
                                                //0.9.2342.19200300.100.1.60
        defaultBinaryAttrs.put("audio", Boolean.TRUE);  //0.9.2342.19200300.100.1.55
        defaultBinaryAttrs.put("thumbnailphoto", Boolean.TRUE);
                                                //1.3.6.1.4.1.1466.101.120.35
        defaultBinaryAttrs.put("thumbnaillogo", Boolean.TRUE);
                                                //1.3.6.1.4.1.1466.101.120.36
        defaultBinaryAttrs.put("usercertificate", Boolean.TRUE);     //2.5.4.36
        defaultBinaryAttrs.put("cacertificate", Boolean.TRUE);       //2.5.4.37
        defaultBinaryAttrs.put("certificaterevocationlist", Boolean.TRUE);
                                                //2.5.4.39
        defaultBinaryAttrs.put("authorityrevocationlist", Boolean.TRUE); //2.5.4.38
        defaultBinaryAttrs.put("crosscertificatepair", Boolean.TRUE);    //2.5.4.40
        defaultBinaryAttrs.put("photo", Boolean.TRUE);   //0.9.2342.19200300.100.1.7
        defaultBinaryAttrs.put("personalsignature", Boolean.TRUE);
                                                //0.9.2342.19200300.100.1.53
        defaultBinaryAttrs.put("x500uniqueidentifier", Boolean.TRUE); //2.5.4.45
    }

    private static final String DISCONNECT_OID = "1.3.6.1.4.1.1466.20036";


    // ----------------------- instance fields ------------------------
    boolean isLdapv3;         // Used by LdapCtx
    int referenceCount = 1;   // Used by LdapCtx for check for sharing

    Connection conn;  // Connection to server; has reader thread
                      // used by LdapCtx for StartTLS

    final private PoolCallback pcb;
    final private boolean pooled;
    private boolean authenticateCalled = false;

    ////////////////////////////////////////////////////////////////////////////
    //
    // constructor: Create an authenticated connection to server
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapClient(String host, int port, String socketFactory,
        int connectTimeout, int readTimeout, OutputStream trace, PoolCallback pcb)
        throws NamingException {

        if (debug > 0)
            System.err.println("LdapClient: constructor called " + host + ":" + port );
        conn = new Connection(this, host, port, socketFactory, connectTimeout, readTimeout,
            trace);

        this.pcb = pcb;
        pooled = (pcb != null);
    }

    synchronized boolean authenticateCalled() {
        return authenticateCalled;
    }

    synchronized LdapResult
    authenticate(boolean initial, String name, Object pw, int version,
        String authMechanism, Control[] ctls,  Hashtable<?,?> env)
        throws NamingException {

        int readTimeout = conn.readTimeout;
        conn.readTimeout = conn.connectTimeout;
        LdapResult res = null;

        try {
            authenticateCalled = true;

            try {
                ensureOpen();
            } catch (IOException e) {
                NamingException ne = new CommunicationException();
                ne.setRootCause(e);
                throw ne;
            }

            switch (version) {
            case LDAP_VERSION3_VERSION2:
            case LDAP_VERSION3:
                isLdapv3 = true;
                break;
            case LDAP_VERSION2:
                isLdapv3 = false;
                break;
            default:
                throw new CommunicationException("Protocol version " + version +
                    " not supported");
            }

            if (authMechanism.equalsIgnoreCase("none") ||
                authMechanism.equalsIgnoreCase("anonymous")) {

                // Perform LDAP bind if we are reauthenticating, using LDAPv2,
                // supporting failover to LDAPv2, or controls have been supplied.
                if (!initial ||
                    (version == LDAP_VERSION2) ||
                    (version == LDAP_VERSION3_VERSION2) ||
                    ((ctls != null) && (ctls.length > 0))) {
                    try {
                        // anonymous bind; update name/pw for LDAPv2 retry
                        res = ldapBind(name=null, (byte[])(pw=null), ctls, null,
                            false);
                        if (res.status == LdapClient.LDAP_SUCCESS) {
                            conn.setBound();
                        }
                    } catch (IOException e) {
                        NamingException ne =
                            new CommunicationException("anonymous bind failed: " +
                            conn.host + ":" + conn.port);
                        ne.setRootCause(e);
                        throw ne;
                    }
                } else {
                    // Skip LDAP bind for LDAPv3 anonymous bind
                    res = new LdapResult();
                    res.status = LdapClient.LDAP_SUCCESS;
                }
            } else if (authMechanism.equalsIgnoreCase("simple")) {
                // simple authentication
                byte[] encodedPw = null;
                try {
                    encodedPw = encodePassword(pw, isLdapv3);
                    res = ldapBind(name, encodedPw, ctls, null, false);
                    if (res.status == LdapClient.LDAP_SUCCESS) {
                        conn.setBound();
                    }
                } catch (IOException e) {
                    NamingException ne =
                        new CommunicationException("simple bind failed: " +
                            conn.host + ":" + conn.port);
                    ne.setRootCause(e);
                    throw ne;
                } finally {
                    // If pw was copied to a new array, clear that array as
                    // a security precaution.
                    if (encodedPw != pw && encodedPw != null) {
                        for (int i = 0; i < encodedPw.length; i++) {
                            encodedPw[i] = 0;
                        }
                    }
                }
            } else if (isLdapv3) {
                // SASL authentication
                try {
                    res = LdapSasl.saslBind(this, conn, conn.host, name, pw,
                        authMechanism, env, ctls);
                    if (res.status == LdapClient.LDAP_SUCCESS) {
                        conn.setBound();
                    }
                } catch (IOException e) {
                    NamingException ne =
                        new CommunicationException("SASL bind failed: " +
                        conn.host + ":" + conn.port);
                    ne.setRootCause(e);
                    throw ne;
                }
            } else {
                throw new AuthenticationNotSupportedException(authMechanism);
            }

            //
            // re-try login using v2 if failing over
            //
            if (initial &&
                (res.status == LdapClient.LDAP_PROTOCOL_ERROR) &&
                (version == LdapClient.LDAP_VERSION3_VERSION2) &&
                (authMechanism.equalsIgnoreCase("none") ||
                    authMechanism.equalsIgnoreCase("anonymous") ||
                    authMechanism.equalsIgnoreCase("simple"))) {

                byte[] encodedPw = null;
                try {
                    isLdapv3 = false;
                    encodedPw = encodePassword(pw, false);
                    res = ldapBind(name, encodedPw, ctls, null, false);
                    if (res.status == LdapClient.LDAP_SUCCESS) {
                        conn.setBound();
                    }
                } catch (IOException e) {
                    NamingException ne =
                        new CommunicationException(authMechanism + ":" +
                            conn.host +     ":" + conn.port);
                    ne.setRootCause(e);
                    throw ne;
                } finally {
                    // If pw was copied to a new array, clear that array as
                    // a security precaution.
                    if (encodedPw != pw && encodedPw != null) {
                        for (int i = 0; i < encodedPw.length; i++) {
                            encodedPw[i] = 0;
                        }
                    }
                }
            }

            // principal name not found
            // (map NameNotFoundException to AuthenticationException)
            // %%% This is a workaround for Netscape servers returning
            // %%% no such object when the principal name is not found
            // %%% Note that when this workaround is applied, it does not allow
            // %%% response controls to be recorded by the calling context
            if (res.status == LdapClient.LDAP_NO_SUCH_OBJECT) {
                throw new AuthenticationException(
                    getErrorMessage(res.status, res.errorMessage));
            }
            conn.setV3(isLdapv3);
            return res;
        } finally {
            conn.readTimeout = readTimeout;
        }
    }

    /**
     * Sends an LDAP Bind request.
     * Cannot be private; called by LdapSasl
     * @param dn The possibly null DN to use in the BIND request. null if anonymous.
     * @param toServer The possibly null array of bytes to send to the server.
     * @param auth The authentication mechanism
     *
     */
    synchronized public LdapResult ldapBind(String dn, byte[]toServer,
        Control[] bindCtls, String auth, boolean pauseAfterReceipt)
        throws java.io.IOException, NamingException {

        ensureOpen();

        // flush outstanding requests
        conn.abandonOutstandingReqs(null);

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();
        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        //
        // build the bind request.
        //
        ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
            ber.encodeInt(curMsgId);
            ber.beginSeq(LdapClient.LDAP_REQ_BIND);
                ber.encodeInt(isLdapv3 ? LDAP_VERSION3 : LDAP_VERSION2);
                ber.encodeString(dn, isLdapv3);

                // if authentication mechanism specified, it is SASL
                if (auth != null) {
                    ber.beginSeq(Ber.ASN_CONTEXT | Ber.ASN_CONSTRUCTOR | 3);
                        ber.encodeString(auth, isLdapv3);    // SASL mechanism
                        if (toServer != null) {
                            ber.encodeOctetString(toServer,
                                Ber.ASN_OCTET_STR);
                        }
                    ber.endSeq();
                } else {
                    if (toServer != null) {
                        ber.encodeOctetString(toServer, Ber.ASN_CONTEXT);
                    } else {
                        ber.encodeOctetString(null, Ber.ASN_CONTEXT, 0, 0);
                    }
                }
            ber.endSeq();

            // Encode controls
            if (isLdapv3) {
                encodeControls(ber, bindCtls);
            }
        ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId, pauseAfterReceipt);
        if (toServer != null) {
            ber.reset();        // clear internally-stored password
        }

        // Read reply
        BerDecoder rber = conn.readReply(req);

        rber.parseSeq(null);    // init seq
        rber.parseInt();        // msg id
        if (rber.parseByte() !=  LDAP_REP_BIND) {
            return res;
        }

        rber.parseLength();
        parseResult(rber, res, isLdapv3);

        // handle server's credentials (if present)
        if (isLdapv3 &&
            (rber.bytesLeft() > 0) &&
            (rber.peekByte() == (Ber.ASN_CONTEXT | 7))) {
            res.serverCreds = rber.parseOctetString((Ber.ASN_CONTEXT | 7), null);
        }

        res.resControls = isLdapv3 ? parseControls(rber) : null;

        conn.removeRequest(req);
        return res;
    }

    /**
     * Determines whether SASL encryption/integrity is in progress.
     * This check is made prior to reauthentication. You cannot reauthenticate
     * over an encrypted/integrity-protected SASL channel. You must
     * close the channel and open a new one.
     */
    boolean usingSaslStreams() {
        return (conn.inStream instanceof SaslInputStream);
    }

    synchronized void incRefCount() {
        ++referenceCount;
        if (debug > 1) {
            System.err.println("LdapClient.incRefCount: " + referenceCount + " " + this);
        }

    }

    /**
     * Returns the encoded password.
     */
    private static byte[] encodePassword(Object pw, boolean v3) throws IOException {

        if (pw instanceof char[]) {
            pw = new String((char[])pw);
        }

        if (pw instanceof String) {
            if (v3) {
                return ((String)pw).getBytes("UTF8");
            } else {
                return ((String)pw).getBytes("8859_1");
            }
        } else {
            return (byte[])pw;
        }
    }

    synchronized void close(Control[] reqCtls, boolean hardClose) {
        --referenceCount;

        if (debug > 1) {
            System.err.println("LdapClient: " + this);
            System.err.println("LdapClient: close() called: " + referenceCount);
            (new Throwable()).printStackTrace();
        }

        if (referenceCount <= 0 && conn != null) {
            if (debug > 0) System.err.println("LdapClient: closed connection " + this);
            if (!pooled) {
                // Not being pooled; continue with closing
                conn.cleanup(reqCtls, false);
                conn = null;
            } else {
                // Pooled

                // Is this a real close or a request to return conn to pool
                if (hardClose) {
                    conn.cleanup(reqCtls, false);
                    conn = null;
                    pcb.removePooledConnection(this);
                } else {
                    pcb.releasePooledConnection(this);
                }
            }
        }
    }

    // NOTE: Should NOT be synchronized otherwise won't be able to close
    private void forceClose(boolean cleanPool) {
        referenceCount = 0; // force closing of connection

        if (debug > 1) {
            System.err.println("LdapClient: forceClose() of " + this);
        }

        if (conn != null) {
            if (debug > 0) System.err.println(
                "LdapClient: forced close of connection " + this);
            conn.cleanup(null, false);
            conn = null;

            if (cleanPool) {
                pcb.removePooledConnection(this);
            }
        }
    }

    protected void finalize() {
        if (debug > 0) System.err.println("LdapClient: finalize " + this);
        forceClose(pooled);
    }

    /*
     * Used by connection pooling to close physical connection.
     */
    synchronized public void closeConnection() {
        forceClose(false); // this is a pool callback so no need to clean pool
    }

    /**
     * Called by Connection.cleanup(). LdapClient should
     * notify any unsolicited listeners and removing itself from any pool.
     * This is almost like forceClose(), except it doesn't call
     * Connection.cleanup() (because this is called from cleanup()).
     */
    void processConnectionClosure() {
        // Notify listeners
        if (unsolicited.size() > 0) {
            String msg;
            if (conn != null) {
                msg = conn.host + ":" + conn.port + " connection closed";
            } else {
                msg = "Connection closed";
            }
            notifyUnsolicited(new CommunicationException(msg));
        }

        // Remove from pool
        if (pooled) {
            pcb.removePooledConnection(this);
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP search. also includes methods to encode rfc 1558 compliant filters
    //
    ////////////////////////////////////////////////////////////////////////////

    static final int SCOPE_BASE_OBJECT = 0;
    static final int SCOPE_ONE_LEVEL = 1;
    static final int SCOPE_SUBTREE = 2;

    LdapResult search(String dn, int scope, int deref, int sizeLimit,
                      int timeLimit, boolean attrsOnly, String attrs[],
                      String filter, int batchSize, Control[] reqCtls,
                      Hashtable<String, Boolean> binaryAttrs,
                      boolean waitFirstReply, int replyQueueCapacity)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_SEARCH);
                    ber.encodeString(dn == null ? "" : dn, isLdapv3);
                    ber.encodeInt(scope, LBER_ENUMERATED);
                    ber.encodeInt(deref, LBER_ENUMERATED);
                    ber.encodeInt(sizeLimit);
                    ber.encodeInt(timeLimit);
                    ber.encodeBoolean(attrsOnly);
                    Filter.encodeFilterString(ber, filter, isLdapv3);
                    ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                        ber.encodeStringArray(attrs, isLdapv3);
                    ber.endSeq();
                ber.endSeq();
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();

         LdapRequest req =
                conn.writeRequest(ber, curMsgId, false, replyQueueCapacity);

         res.msgId = curMsgId;
         res.status = LdapClient.LDAP_SUCCESS; //optimistic
         if (waitFirstReply) {
             // get first reply
             res = getSearchReply(req, batchSize, res, binaryAttrs);
         }
         return res;
    }

    /*
     * Abandon the search operation and remove it from the message queue.
     */
    void clearSearchReply(LdapResult res, Control[] ctls) {
        if (res != null && conn != null) {

            // Only send an LDAP abandon operation when clearing the search
            // reply from a one-level or subtree search.
            LdapRequest req = conn.findRequest(res.msgId);
            if (req == null) {
                return;
            }

            // OK if req got removed after check; double removal attempt
            // but otherwise no harm done

            // Send an LDAP abandon only if the search operation has not yet
            // completed.
            if (req.hasSearchCompleted()) {
                conn.removeRequest(req);
            } else {
                conn.abandonRequest(req, ctls);
            }
        }
    }

    /*
     * Retrieve the next batch of entries and/or referrals.
     */
    LdapResult getSearchReply(int batchSize, LdapResult res,
        Hashtable<String, Boolean> binaryAttrs) throws IOException, NamingException {

        ensureOpen();

        LdapRequest req;

        if ((req = conn.findRequest(res.msgId)) == null) {
            return null;
        }

        return getSearchReply(req, batchSize, res, binaryAttrs);
    }

    private LdapResult getSearchReply(LdapRequest req,
        int batchSize, LdapResult res, Hashtable<String, Boolean> binaryAttrs)
        throws IOException, NamingException {

        if (batchSize == 0)
            batchSize = Integer.MAX_VALUE;

        if (res.entries != null) {
            res.entries.setSize(0); // clear the (previous) set of entries
        } else {
            res.entries =
                new Vector<>(batchSize == Integer.MAX_VALUE ? 32 : batchSize);
        }

        if (res.referrals != null) {
            res.referrals.setSize(0); // clear the (previous) set of referrals
        }

        BerDecoder replyBer;    // Decoder for response
        int seq;                // Request id

        Attributes lattrs;      // Attribute set read from response
        Attribute la;           // Attribute read from response
        String DN;              // DN read from response
        LdapEntry le;           // LDAP entry representing response
        int[] seqlen;           // Holder for response length
        int endseq;             // Position of end of response

        for (int i = 0; i < batchSize;) {
            replyBer = conn.readReply(req);

            //
            // process search reply
            //
            replyBer.parseSeq(null);                    // init seq
            replyBer.parseInt();                        // req id
            seq = replyBer.parseSeq(null);

            if (seq == LDAP_REP_SEARCH) {

                // handle LDAPv3 search entries
                lattrs = new BasicAttributes(caseIgnore);
                DN = replyBer.parseString(isLdapv3);
                le = new LdapEntry(DN, lattrs);
                seqlen = new int[1];

                replyBer.parseSeq(seqlen);
                endseq = replyBer.getParsePosition() + seqlen[0];
                while ((replyBer.getParsePosition() < endseq) &&
                    (replyBer.bytesLeft() > 0)) {
                    la = parseAttribute(replyBer, binaryAttrs);
                    lattrs.put(la);
                }
                le.respCtls = isLdapv3 ? parseControls(replyBer) : null;

                res.entries.addElement(le);
                i++;

            } else if ((seq == LDAP_REP_SEARCH_REF) && isLdapv3) {

                // handle LDAPv3 search reference
                Vector<String> URLs = new Vector<>(4);

                // %%% Although not strictly correct, some LDAP servers
                //     encode the SEQUENCE OF tag in the SearchResultRef
                if (replyBer.peekByte() ==
                    (Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR)) {
                    replyBer.parseSeq(null);
                }

                while ((replyBer.bytesLeft() > 0) &&
                    (replyBer.peekByte() == Ber.ASN_OCTET_STR)) {

                    URLs.addElement(replyBer.parseString(isLdapv3));
                }

                if (res.referrals == null) {
                    res.referrals = new Vector<>(4);
                }
                res.referrals.addElement(URLs);
                res.resControls = isLdapv3 ? parseControls(replyBer) : null;

                // Save referral and continue to get next search result

            } else if (seq == LDAP_REP_EXTENSION) {

                parseExtResponse(replyBer, res); //%%% ignore for now

            } else if (seq == LDAP_REP_RESULT) {

                parseResult(replyBer, res, isLdapv3);
                res.resControls = isLdapv3 ? parseControls(replyBer) : null;

                conn.removeRequest(req);
                return res;     // Done with search
            }
        }

        return res;
    }

    private Attribute parseAttribute(BerDecoder ber,
                                     Hashtable<String, Boolean> binaryAttrs)
        throws IOException {

        int len[] = new int[1];
        int seq = ber.parseSeq(null);
        String attrid = ber.parseString(isLdapv3);
        boolean hasBinaryValues = isBinaryValued(attrid, binaryAttrs);
        Attribute la = new LdapAttribute(attrid);

        if ((seq = ber.parseSeq(len)) == LBER_SET) {
            int attrlen = len[0];
            while (ber.bytesLeft() > 0 && attrlen > 0) {
                try {
                    attrlen -= parseAttributeValue(ber, la, hasBinaryValues);
                } catch (IOException ex) {
                    ber.seek(attrlen);
                    break;
                }
            }
        } else {
            // Skip the rest of the sequence because it is not what we want
            ber.seek(len[0]);
        }
        return la;
    }

    //
    // returns number of bytes that were parsed. Adds the values to attr
    //
    private int parseAttributeValue(BerDecoder ber, Attribute la,
        boolean hasBinaryValues) throws IOException {

        int len[] = new int[1];

        if (hasBinaryValues) {
            la.add(ber.parseOctetString(ber.peekByte(), len));
        } else {
            la.add(ber.parseStringWithTag(
                                    Ber.ASN_SIMPLE_STRING, isLdapv3, len));
        }
        return len[0];
    }

    private boolean isBinaryValued(String attrid,
                                   Hashtable<String, Boolean> binaryAttrs) {
        String id = attrid.toLowerCase(Locale.ENGLISH);

        return ((id.indexOf(";binary") != -1) ||
            defaultBinaryAttrs.containsKey(id) ||
            ((binaryAttrs != null) && (binaryAttrs.containsKey(id))));
    }

    // package entry point; used by Connection
    static void parseResult(BerDecoder replyBer, LdapResult res,
            boolean isLdapv3) throws IOException {

        res.status = replyBer.parseEnumeration();
        res.matchedDN = replyBer.parseString(isLdapv3);
        res.errorMessage = replyBer.parseString(isLdapv3);

        // handle LDAPv3 referrals (if present)
        if (isLdapv3 &&
            (replyBer.bytesLeft() > 0) &&
            (replyBer.peekByte() == LDAP_REP_REFERRAL)) {

            Vector<String> URLs = new Vector<>(4);
            int[] seqlen = new int[1];

            replyBer.parseSeq(seqlen);
            int endseq = replyBer.getParsePosition() + seqlen[0];
            while ((replyBer.getParsePosition() < endseq) &&
                (replyBer.bytesLeft() > 0)) {

                URLs.addElement(replyBer.parseString(isLdapv3));
            }

            if (res.referrals == null) {
                res.referrals = new Vector<>(4);
            }
            res.referrals.addElement(URLs);
        }
    }

    // package entry point; used by Connection
    static Vector<Control> parseControls(BerDecoder replyBer) throws IOException {

        // handle LDAPv3 controls (if present)
        if ((replyBer.bytesLeft() > 0) && (replyBer.peekByte() == LDAP_CONTROLS)) {
            Vector<Control> ctls = new Vector<>(4);
            String controlOID;
            boolean criticality = false; // default
            byte[] controlValue = null;  // optional
            int[] seqlen = new int[1];

            replyBer.parseSeq(seqlen);
            int endseq = replyBer.getParsePosition() + seqlen[0];
            while ((replyBer.getParsePosition() < endseq) &&
                (replyBer.bytesLeft() > 0)) {

                replyBer.parseSeq(null);
                controlOID = replyBer.parseString(true);

                if ((replyBer.bytesLeft() > 0) &&
                    (replyBer.peekByte() == Ber.ASN_BOOLEAN)) {
                    criticality = replyBer.parseBoolean();
                }
                if ((replyBer.bytesLeft() > 0) &&
                    (replyBer.peekByte() == Ber.ASN_OCTET_STR)) {
                    controlValue =
                        replyBer.parseOctetString(Ber.ASN_OCTET_STR, null);
                }
                if (controlOID != null) {
                    ctls.addElement(
                        new BasicControl(controlOID, criticality, controlValue));
                }
            }
            return ctls;
        } else {
            return null;
        }
    }

    private void parseExtResponse(BerDecoder replyBer, LdapResult res)
        throws IOException {

        parseResult(replyBer, res, isLdapv3);

        if ((replyBer.bytesLeft() > 0) &&
            (replyBer.peekByte() == LDAP_REP_EXT_OID)) {
            res.extensionId =
                replyBer.parseStringWithTag(LDAP_REP_EXT_OID, isLdapv3, null);
        }
        if ((replyBer.bytesLeft() > 0) &&
            (replyBer.peekByte() == LDAP_REP_EXT_VAL)) {
            res.extensionValue =
                replyBer.parseOctetString(LDAP_REP_EXT_VAL, null);
        }

        res.resControls = parseControls(replyBer);
    }

    //
    // Encode LDAPv3 controls
    //
    static void encodeControls(BerEncoder ber, Control[] reqCtls)
        throws IOException {

        if ((reqCtls == null) || (reqCtls.length == 0)) {
            return;
        }

        byte[] controlVal;

        ber.beginSeq(LdapClient.LDAP_CONTROLS);

            for (int i = 0; i < reqCtls.length; i++) {
                ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                    ber.encodeString(reqCtls[i].getID(), true); // control OID
                    if (reqCtls[i].isCritical()) {
                        ber.encodeBoolean(true); // critical control
                    }
                    if ((controlVal = reqCtls[i].getEncodedValue()) != null) {
                        ber.encodeOctetString(controlVal, Ber.ASN_OCTET_STR);
                    }
                ber.endSeq();
            }
        ber.endSeq();
    }

    /**
     * Reads the next reply corresponding to msgId, outstanding on requestBer.
     * Processes the result and any controls.
     */
    private LdapResult processReply(LdapRequest req,
        LdapResult res, int responseType) throws IOException, NamingException {

        BerDecoder rber = conn.readReply(req);

        rber.parseSeq(null);    // init seq
        rber.parseInt();        // msg id
        if (rber.parseByte() !=  responseType) {
            return res;
        }

        rber.parseLength();
        parseResult(rber, res, isLdapv3);
        res.resControls = isLdapv3 ? parseControls(rber) : null;

        conn.removeRequest(req);

        return res;     // Done with operation
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP modify:
    //  Modify the DN dn with the operations on attributes attrs.
    //  ie, operations[0] is the operation to be performed on
    //  attrs[0];
    //          dn - DN to modify
    //          operations - add, delete or replace
    //          attrs - array of Attribute
    //          reqCtls - array of request controls
    //
    ////////////////////////////////////////////////////////////////////////////

    static final int ADD = 0;
    static final int DELETE = 1;
    static final int REPLACE = 2;

    LdapResult modify(String dn, int operations[], Attribute attrs[],
                      Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (dn == null || operations.length != attrs.length)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

        ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
            ber.encodeInt(curMsgId);
            ber.beginSeq(LDAP_REQ_MODIFY);
                ber.encodeString(dn, isLdapv3);
                ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                    for (int i = 0; i < operations.length; i++) {
                        ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                            ber.encodeInt(operations[i], LBER_ENUMERATED);

                            // zero values is not permitted for the add op.
                            if ((operations[i] == ADD) && hasNoValue(attrs[i])) {
                                throw new InvalidAttributeValueException(
                                    "'" + attrs[i].getID() + "' has no values.");
                            } else {
                                encodeAttribute(ber, attrs[i]);
                            }
                        ber.endSeq();
                    }
                ber.endSeq();
            ber.endSeq();
            if (isLdapv3) encodeControls(ber, reqCtls);
        ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId);

        return processReply(req, res, LDAP_REP_MODIFY);
    }

    private void encodeAttribute(BerEncoder ber, Attribute attr)
        throws IOException, NamingException {

        ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
            ber.encodeString(attr.getID(), isLdapv3);
            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR | 1);
                NamingEnumeration<?> enum_ = attr.getAll();
                Object val;
                while (enum_.hasMore()) {
                    val = enum_.next();
                    if (val instanceof String) {
                        ber.encodeString((String)val, isLdapv3);
                    } else if (val instanceof byte[]) {
                        ber.encodeOctetString((byte[])val, Ber.ASN_OCTET_STR);
                    } else if (val == null) {
                        // no attribute value
                    } else {
                        throw new InvalidAttributeValueException(
                            "Malformed '" + attr.getID() + "' attribute value");
                    }
                }
            ber.endSeq();
        ber.endSeq();
    }

    private static boolean hasNoValue(Attribute attr) throws NamingException {
        return attr.size() == 0 || (attr.size() == 1 && attr.get() == null);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP add
    //          Adds entry to the Directory
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult add(LdapEntry entry, Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (entry == null || entry.DN == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();
        Attribute attr;

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_ADD);
                    ber.encodeString(entry.DN, isLdapv3);
                    ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                        NamingEnumeration<? extends Attribute> enum_ =
                                entry.attributes.getAll();
                        while (enum_.hasMore()) {
                            attr = enum_.next();

                            // zero values is not permitted
                            if (hasNoValue(attr)) {
                                throw new InvalidAttributeValueException(
                                    "'" + attr.getID() + "' has no values.");
                            } else {
                                encodeAttribute(ber, attr);
                            }
                        }
                    ber.endSeq();
                ber.endSeq();
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId);
        return processReply(req, res, LDAP_REP_ADD);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP delete
    //          deletes entry from the Directory
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult delete(String DN, Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (DN == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.encodeString(DN, LDAP_REQ_DELETE, isLdapv3);
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId);

        return processReply(req, res, LDAP_REP_DELETE);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP modrdn
    //  Changes the last element of DN to newrdn
    //          dn - DN to change
    //          newrdn - new RDN to rename to
    //          deleteoldrdn - boolean whether to delete old attrs or not
    //          newSuperior - new place to put the entry in the tree
    //                        (ignored if server is LDAPv2)
    //          reqCtls - array of request controls
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult moddn(String DN, String newrdn, boolean deleteOldRdn,
                     String newSuperior, Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        boolean changeSuperior = (newSuperior != null &&
                                  newSuperior.length() > 0);

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (DN == null || newrdn == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_MODRDN);
                    ber.encodeString(DN, isLdapv3);
                    ber.encodeString(newrdn, isLdapv3);
                    ber.encodeBoolean(deleteOldRdn);
                    if(isLdapv3 && changeSuperior) {
                        //System.err.println("changin superior");
                        ber.encodeString(newSuperior, LDAP_SUPERIOR_DN, isLdapv3);
                    }
                ber.endSeq();
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();


        LdapRequest req = conn.writeRequest(ber, curMsgId);

        return processReply(req, res, LDAP_REP_MODRDN);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP compare
    //  Compare attribute->value pairs in dn
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult compare(String DN, String type, String value, Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (DN == null || type == null || value == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_COMPARE);
                    ber.encodeString(DN, isLdapv3);
                    ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                        ber.encodeString(type, isLdapv3);

                        // replace any escaped characters in the value
                        byte[] val = isLdapv3 ?
                            value.getBytes("UTF8") : value.getBytes("8859_1");
                        ber.encodeOctetString(
                            Filter.unescapeFilterValue(val, 0, val.length),
                            Ber.ASN_OCTET_STR);

                    ber.endSeq();
                ber.endSeq();
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId);

        return processReply(req, res, LDAP_REP_COMPARE);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP extended operation
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult extendedOp(String id, byte[] request, Control[] reqCtls,
        boolean pauseAfterReceipt) throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (id == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_EXTENSION);
                    ber.encodeString(id,
                        Ber.ASN_CONTEXT | 0, isLdapv3);//[0]
                    if (request != null) {
                        ber.encodeOctetString(request,
                            Ber.ASN_CONTEXT | 1);//[1]
                    }
                ber.endSeq();
                encodeControls(ber, reqCtls); // always v3
            ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId, pauseAfterReceipt);

        BerDecoder rber = conn.readReply(req);

        rber.parseSeq(null);    // init seq
        rber.parseInt();        // msg id
        if (rber.parseByte() !=  LDAP_REP_EXTENSION) {
            return res;
        }

        rber.parseLength();
        parseExtResponse(rber, res);
        conn.removeRequest(req);

        return res;     // Done with operation
    }



    ////////////////////////////////////////////////////////////////////////////
    //
    // Some BER definitions convenient for LDAP
    //
    ////////////////////////////////////////////////////////////////////////////

    static final int LDAP_VERSION3_VERSION2 = 32;
    static final int LDAP_VERSION2 = 0x02;
    static final int LDAP_VERSION3 = 0x03;              // LDAPv3
    static final int LDAP_VERSION = LDAP_VERSION3;

    static final int LDAP_REF_FOLLOW = 0x01;            // follow referrals
    static final int LDAP_REF_THROW = 0x02;             // throw referral ex.
    static final int LDAP_REF_IGNORE = 0x03;            // ignore referrals

    static final String LDAP_URL = "ldap://";           // LDAPv3
    static final String LDAPS_URL = "ldaps://";         // LDAPv3

    static final int LBER_BOOLEAN = 0x01;
    static final int LBER_INTEGER = 0x02;
    static final int LBER_BITSTRING = 0x03;
    static final int LBER_OCTETSTRING = 0x04;
    static final int LBER_NULL = 0x05;
    static final int LBER_ENUMERATED = 0x0a;
    static final int LBER_SEQUENCE = 0x30;
    static final int LBER_SET = 0x31;

    static final int LDAP_SUPERIOR_DN = 0x80;

    static final int LDAP_REQ_BIND = 0x60;      // app + constructed
    static final int LDAP_REQ_UNBIND = 0x42;    // app + primitive
    static final int LDAP_REQ_SEARCH = 0x63;    // app + constructed
    static final int LDAP_REQ_MODIFY = 0x66;    // app + constructed
    static final int LDAP_REQ_ADD = 0x68;       // app + constructed
    static final int LDAP_REQ_DELETE = 0x4a;    // app + primitive
    static final int LDAP_REQ_MODRDN = 0x6c;    // app + constructed
    static final int LDAP_REQ_COMPARE = 0x6e;   // app + constructed
    static final int LDAP_REQ_ABANDON = 0x50;   // app + primitive
    static final int LDAP_REQ_EXTENSION = 0x77; // app + constructed    (LDAPv3)

    static final int LDAP_REP_BIND = 0x61;      // app + constructed | 1
    static final int LDAP_REP_SEARCH = 0x64;    // app + constructed | 4
    static final int LDAP_REP_SEARCH_REF = 0x73;// app + constructed    (LDAPv3)
    static final int LDAP_REP_RESULT = 0x65;    // app + constructed | 5
    static final int LDAP_REP_MODIFY = 0x67;    // app + constructed | 7
    static final int LDAP_REP_ADD = 0x69;       // app + constructed | 9
    static final int LDAP_REP_DELETE = 0x6b;    // app + primitive | b
    static final int LDAP_REP_MODRDN = 0x6d;    // app + primitive | d
    static final int LDAP_REP_COMPARE = 0x6f;   // app + primitive | f
    static final int LDAP_REP_EXTENSION = 0x78; // app + constructed    (LDAPv3)

    static final int LDAP_REP_REFERRAL = 0xa3;  // ctx + constructed    (LDAPv3)
    static final int LDAP_REP_EXT_OID = 0x8a;   // ctx + primitive      (LDAPv3)
    static final int LDAP_REP_EXT_VAL = 0x8b;   // ctx + primitive      (LDAPv3)

    // LDAPv3 Controls

    static final int LDAP_CONTROLS = 0xa0;      // ctx + constructed    (LDAPv3)
    static final String LDAP_CONTROL_MANAGE_DSA_IT = "2.16.840.1.113730.3.4.2";
    static final String LDAP_CONTROL_PREFERRED_LANG = "1.3.6.1.4.1.1466.20035";
    static final String LDAP_CONTROL_PAGED_RESULTS = "1.2.840.113556.1.4.319";
    static final String LDAP_CONTROL_SERVER_SORT_REQ = "1.2.840.113556.1.4.473";
    static final String LDAP_CONTROL_SERVER_SORT_RES = "1.2.840.113556.1.4.474";

    ////////////////////////////////////////////////////////////////////////////
    //
    // return codes
    //
    ////////////////////////////////////////////////////////////////////////////

    static final int LDAP_SUCCESS = 0;
    static final int LDAP_OPERATIONS_ERROR = 1;
    static final int LDAP_PROTOCOL_ERROR = 2;
    static final int LDAP_TIME_LIMIT_EXCEEDED = 3;
    static final int LDAP_SIZE_LIMIT_EXCEEDED = 4;
    static final int LDAP_COMPARE_FALSE = 5;
    static final int LDAP_COMPARE_TRUE = 6;
    static final int LDAP_AUTH_METHOD_NOT_SUPPORTED = 7;
    static final int LDAP_STRONG_AUTH_REQUIRED = 8;
    static final int LDAP_PARTIAL_RESULTS = 9;                  // Slapd
    static final int LDAP_REFERRAL = 10;                        // LDAPv3
    static final int LDAP_ADMIN_LIMIT_EXCEEDED = 11;            // LDAPv3
    static final int LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12;  // LDAPv3
    static final int LDAP_CONFIDENTIALITY_REQUIRED = 13;        // LDAPv3
    static final int LDAP_SASL_BIND_IN_PROGRESS = 14;           // LDAPv3
    static final int LDAP_NO_SUCH_ATTRIBUTE = 16;
    static final int LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17;
    static final int LDAP_INAPPROPRIATE_MATCHING = 18;
    static final int LDAP_CONSTRAINT_VIOLATION = 19;
    static final int LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20;
    static final int LDAP_INVALID_ATTRIBUTE_SYNTAX = 21;
    static final int LDAP_NO_SUCH_OBJECT = 32;
    static final int LDAP_ALIAS_PROBLEM = 33;
    static final int LDAP_INVALID_DN_SYNTAX = 34;
    static final int LDAP_IS_LEAF = 35;
    static final int LDAP_ALIAS_DEREFERENCING_PROBLEM = 36;
    static final int LDAP_INAPPROPRIATE_AUTHENTICATION = 48;
    static final int LDAP_INVALID_CREDENTIALS = 49;
    static final int LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50;
    static final int LDAP_BUSY = 51;
    static final int LDAP_UNAVAILABLE = 52;
    static final int LDAP_UNWILLING_TO_PERFORM = 53;
    static final int LDAP_LOOP_DETECT = 54;
    static final int LDAP_NAMING_VIOLATION = 64;
    static final int LDAP_OBJECT_CLASS_VIOLATION = 65;
    static final int LDAP_NOT_ALLOWED_ON_NON_LEAF = 66;
    static final int LDAP_NOT_ALLOWED_ON_RDN = 67;
    static final int LDAP_ENTRY_ALREADY_EXISTS = 68;
    static final int LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69;
    static final int LDAP_AFFECTS_MULTIPLE_DSAS = 71;           // LDAPv3
    static final int LDAP_OTHER = 80;

    static final String[] ldap_error_message = {
        "Success",                                      // 0
        "Operations Error",                             // 1
        "Protocol Error",                               // 2
        "Timelimit Exceeded",                           // 3
        "Sizelimit Exceeded",                           // 4
        "Compare False",                                // 5
        "Compare True",                                 // 6
        "Authentication Method Not Supported",          // 7
        "Strong Authentication Required",               // 8
        null,
        "Referral",                                     // 10
        "Administrative Limit Exceeded",                // 11
        "Unavailable Critical Extension",               // 12
        "Confidentiality Required",                     // 13
        "SASL Bind In Progress",                        // 14
        null,
        "No Such Attribute",                            // 16
        "Undefined Attribute Type",                     // 17
        "Inappropriate Matching",                       // 18
        "Constraint Violation",                         // 19
        "Attribute Or Value Exists",                    // 20
        "Invalid Attribute Syntax",                     // 21
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        "No Such Object",                               // 32
        "Alias Problem",                                // 33
        "Invalid DN Syntax",                            // 34
        null,
        "Alias Dereferencing Problem",                  // 36
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        "Inappropriate Authentication",                 // 48
        "Invalid Credentials",                          // 49
        "Insufficient Access Rights",                   // 50
        "Busy",                                         // 51
        "Unavailable",                                  // 52
        "Unwilling To Perform",                         // 53
        "Loop Detect",                                  // 54
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        "Naming Violation",                             // 64
        "Object Class Violation",                       // 65
        "Not Allowed On Non-leaf",                      // 66
        "Not Allowed On RDN",                           // 67
        "Entry Already Exists",                         // 68
        "Object Class Modifications Prohibited",        // 69
        null,
        "Affects Multiple DSAs",                        // 71
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        "Other",                                        // 80
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null
    };


    /*
     * Generate an error message from the LDAP error code and error diagnostic.
     * The message format is:
     *
     *     "[LDAP: error code <errorCode> - <errorMessage>]"
     *
     * where <errorCode> is a numeric error code
     * and <errorMessage> is a textual description of the error (if available)
     *
     */
    static String getErrorMessage(int errorCode, String errorMessage) {

        String message = "[LDAP: error code " + errorCode;

        if ((errorMessage != null) && (errorMessage.length() != 0)) {

            // append error message from the server
            message = message + " - " + errorMessage + "]";

        } else {

            // append built-in error message
            try {
                if (ldap_error_message[errorCode] != null) {
                    message = message + " - " + ldap_error_message[errorCode] +
                                "]";
                }
            } catch (ArrayIndexOutOfBoundsException ex) {
                message = message + "]";
            }
        }
        return message;
    }


    ////////////////////////////////////////////////////////////////////////////
    //
    // Unsolicited notification support.
    //
    // An LdapClient maintains a list of LdapCtx that have registered
    // for UnsolicitedNotifications. This is a list because a single
    // LdapClient might be shared among multiple contexts.
    //
    // When addUnsolicited() is invoked, the LdapCtx is added to the list.
    //
    // When Connection receives an unsolicited notification (msgid == 0),
    // it invokes LdapClient.processUnsolicited(). processUnsolicited()
    // parses the Extended Response. If there are registered listeners,
    // LdapClient creates an UnsolicitedNotification from the response
    // and informs each LdapCtx to fire an event for the notification.
    // If it is a DISCONNECT notification, the connection is closed and a
    // NamingExceptionEvent is fired to the listeners.
    //
    // When the connection is closed out-of-band like this, the next
    // time a method is invoked on LdapClient, an IOException is thrown.
    //
    // removeUnsolicited() is invoked to remove an LdapCtx from this client.
    //
    ////////////////////////////////////////////////////////////////////////////
    private Vector<LdapCtx> unsolicited = new Vector<>(3);
    void addUnsolicited(LdapCtx ctx) {
        if (debug > 0) {
            System.err.println("LdapClient.addUnsolicited" + ctx);
        }
        unsolicited.addElement(ctx);
    }

    void removeUnsolicited(LdapCtx ctx) {
        if (debug > 0) {
            System.err.println("LdapClient.removeUnsolicited" + ctx);
        }
            unsolicited.removeElement(ctx);
        }

    // NOTE: Cannot be synchronized because this is called asynchronously
    // by the reader thread in Connection. Instead, sync on 'unsolicited' Vector.
    void processUnsolicited(BerDecoder ber) {
        if (debug > 0) {
            System.err.println("LdapClient.processUnsolicited");
        }
        try {
            // Parse the response
            LdapResult res = new LdapResult();

            ber.parseSeq(null); // init seq
            ber.parseInt();             // msg id; should be 0; ignored
            if (ber.parseByte() != LDAP_REP_EXTENSION) {
                throw new IOException(
                    "Unsolicited Notification must be an Extended Response");
            }
            ber.parseLength();
            parseExtResponse(ber, res);

            if (DISCONNECT_OID.equals(res.extensionId)) {
                // force closing of connection
                forceClose(pooled);
            }

            LdapCtx first = null;
            UnsolicitedNotification notice = null;

            synchronized (unsolicited) {
                if (unsolicited.size() > 0) {
                    first = unsolicited.elementAt(0);

                    // Create an UnsolicitedNotification using the parsed data
                    // Need a 'ctx' object because we want to use the context's
                    // list of provider control factories.
                    notice = new UnsolicitedResponseImpl(
                        res.extensionId,
                        res.extensionValue,
                        res.referrals,
                        res.status,
                        res.errorMessage,
                        res.matchedDN,
                        (res.resControls != null) ?
                        first.convertControls(res.resControls) :
                        null);
                }
            }

            if (notice != null) {
                // Fire UnsolicitedNotification events to listeners
                notifyUnsolicited(notice);

                // If "disconnect" notification,
                // notify unsolicited listeners via NamingException
                if (DISCONNECT_OID.equals(res.extensionId)) {
                    notifyUnsolicited(
                        new CommunicationException("Connection closed"));
                }
            }
        } catch (IOException e) {
            NamingException ne = new CommunicationException(
                "Problem parsing unsolicited notification");
            ne.setRootCause(e);

            notifyUnsolicited(ne);

        } catch (NamingException e) {
            notifyUnsolicited(e);
        }
    }


    private void notifyUnsolicited(Object e) {
        Vector<LdapCtx> unsolicitedCopy;
        synchronized (unsolicited) {
            unsolicitedCopy = new Vector<>(unsolicited);
            if (e instanceof NamingException) {
                unsolicited.setSize(0);  // no more listeners after exception
            }
        }
        for (int i = 0; i < unsolicitedCopy.size(); i++) {
            unsolicitedCopy.elementAt(i).fireUnsolicited(e);
        }
    }

    private void ensureOpen() throws IOException {
        if (conn == null || !conn.useable) {
            if (conn != null && conn.closureReason != null) {
                throw conn.closureReason;
            } else {
                throw new IOException("connection closed");
            }
        }
    }

    // package private (used by LdapCtx)
    static LdapClient getInstance(boolean usePool, String hostname, int port,
        String factory, int connectTimeout, int readTimeout, OutputStream trace,
        int version, String authMechanism, Control[] ctls, String protocol,
        String user, Object passwd, Hashtable<?,?> env) throws NamingException {

        if (usePool) {
            if (LdapPoolManager.isPoolingAllowed(factory, trace,
                    authMechanism, protocol, env)) {
                LdapClient answer = LdapPoolManager.getLdapClient(
                        hostname, port, factory, connectTimeout, readTimeout,
                        trace, version, authMechanism, ctls, protocol, user,
                        passwd, env);
                answer.referenceCount = 1;   // always one when starting out
                return answer;
            }
        }
        return new LdapClient(hostname, port, factory, connectTimeout,
                                        readTimeout, trace, null);
    }
}
