124. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 9/25/2018 2:13:04 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

124.1 Files compared

# Location File Last Modified
1 build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\jndi\ldap LdapClient.java Mon Jan 22 14:46:50 2018 UTC
2 build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\com\sun\jndi\ldap LdapClient.java Wed Sep 12 16:27:35 2018 UTC

124.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 3234
Changed 1 2
Inserted 0 0
Removed 0 0

124.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

124.4 Active regular expressions

No regular expressions were active.

124.5 Comparison detail

  1   /*
  2    * Copyrig ht (c) 199 9, 2017, O racle and/ or its aff iliates. A ll rights  reserved.
  3    * DO NOT  ALTER OR R EMOVE COPY RIGHT NOTI CES OR THI S FILE HEA DER.
  4    *
  5    * This co de is free  software;  you can r edistribut e it and/o r modify i t
  6    * under t he terms o f the GNU  General Pu blic Licen se version  2 only, a s
  7    * publish ed by the  Free Softw are Founda tion.  Ora cle design ates this
  8    * particu lar file a s subject  to the "Cl asspath" e xception a s provided
  9    * by Orac le in the  LICENSE fi le that ac companied  this code.
  10    *
  11    * This co de is dist ributed in  the hope  that it wi ll be usef ul, but WI THOUT
  12    * ANY WAR RANTY; wit hout even  the implie d warranty  of MERCHA NTABILITY  or
  13    * FITNESS  FOR A PAR TICULAR PU RPOSE.  Se e the GNU  General Pu blic Licen se
  14    * version  2 for mor e details  (a copy is  included  in the LIC ENSE file  that
  15    * accompa nied this  code).
  16    *
  17    * You sho uld have r eceived a  copy of th e GNU Gene ral Public  License v ersion
  18    * 2 along  with this  work; if  not, write  to the Fr ee Softwar e Foundati on,
  19    * Inc., 5 1 Franklin  St, Fifth  Floor, Bo ston, MA 0 2110-1301  USA.
  20    *
  21    * Please  contact Or acle, 500  Oracle Par kway, Redw ood Shores , CA 94065  USA
  22    * or visi t www.orac le.com if  you need a dditional  informatio n or have  any
  23    * questio ns.
  24    */
  25  
  26   package co m.sun.jndi .ldap;
  27  
  28   import jav a.io.*;
  29   import jav a.util.Loc ale;
  30   import jav a.util.Vec tor;
  31   import jav a.util.Has htable;
  32  
  33   import jav ax.naming. *;
  34   import jav ax.naming. directory. *;
  35   import jav ax.naming. ldap.*;
  36  
  37   import com .sun.jndi. ldap.pool. PooledConn ection;
  38   import com .sun.jndi. ldap.pool. PoolCallba ck;
  39   import com .sun.jndi. ldap.sasl. LdapSasl;
  40   import com .sun.jndi. ldap.sasl. SaslInputS tream;
  41  
  42   /**
  43    * LDAP (R FC-1777) a nd LDAPv3  (RFC-2251)  compliant  client
  44    *
  45    * This cl ass repres ents a con nection to  an LDAP c lient.
  46    * Callers  interact  with this  class at a n LDAP ope ration lev el.
  47    * That is , the call er invokes  a method  to do a SE ARCH or MO DRDN
  48    * operati on and get s back the  result.
  49    * The cal ler uses t he constru ctor to cr eate a con nection to  the serve r.
  50    * It then  needs to  use authen ticate() t o perform  an LDAP BI ND.
  51    * Note th at for v3,  BIND is o ptional so  authentic ate() migh t not
  52    * actuall y send a B IND. authe nticate()  can be use d later on  to issue
  53    * a BIND,  for examp le, for a  v3 client  that wants  to change  the conne ction's
  54    * credent ials.
  55    *<p>
  56    * Multipl e LdapCtx  might shar e the same  LdapClien t. For exa mple, cont exts
  57    * derived  from the  same initi al context  would sha re the sam e LdapClie nt
  58    * until c hanges to  a context' s properti es necessi tates its  own LdapCl ient.
  59    * LdapCli ent method s that acc ess shared  data are  thread-saf e (i.e., c aller
  60    * does no t have to  sync).
  61    *<p>
  62    * Fields:
  63    *   isLda pv3 - no s ync; initi alized and  updated w ithin sync  authentic ate();
  64    *       a lways upda ted when c onnection  is "quiet"  and not s hared;
  65    *       r ead access  from outs ide LdapCl ient not s ync
  66    *   refer enceCount  - sync wit hin LdapCl ient; exce ption is f orceClose( ) which
  67    *       i s used by  Connection  thread to  close con nection up on receivi ng
  68    *       a n Unsolici ted Notifi cation.
  69    *       a ccess from  outside L dapClient  must sync;
  70    *   conn  - no sync;  Connectio n takes ca re of its  own sync
  71    *   unsol icited - s ync Vector ; multiple  operation s sync'ed
  72    *
  73    * @author  Vincent R yan
  74    * @author  Jagane Su ndar
  75    * @author  Rosanna L ee
  76    */
  77  
  78   public fin al class L dapClient  implements  PooledCon nection {
  79       // --- ---------- ---------  Constants  ---------- ---------- ---------- ----
  80       privat e static f inal int d ebug = 0;
  81       static  final boo lean caseI gnore = tr ue;
  82  
  83       // Def ault list  of binary  attributes
  84       privat e static f inal Hasht able<Strin g, Boolean > defaultB inaryAttrs  =
  85                new Hash table<>(23 ,0.75f);
  86       static  {
  87             defaultBin aryAttrs.p ut("userpa ssword", B oolean.TRU E);        // DNS      
  88           de faultBinar yAttrs.put ("javaseri alizeddata ", Boolean .TRUE);
  89                                                       // 1.3.6.1.4. 1.42.2.27. 4.1.8
  90           de faultBinar yAttrs.put ("javaseri alizedobje ct", Boole an.TRUE);
  91                                                       //  1.3.6.1.4 .1.42.2.27 .4.1.2
  92           de faultBinar yAttrs.put ("jpegphot o", Boolea n.TRUE);
  93                                                       // 0.9.2342.1 9200300.10 0.1.60
  94           de faultBinar yAttrs.put ("audio",  Boolean.TR UE);  //0. 9.2342.192 00300.100. 1.55
  95           de faultBinar yAttrs.put ("thumbnai lphoto", B oolean.TRU E);
  96                                                       // 1.3.6.1.4. 1.1466.101 .120.35
  97           de faultBinar yAttrs.put ("thumbnai llogo", Bo olean.TRUE );
  98                                                       // 1.3.6.1.4. 1.1466.101 .120.36
  99           de faultBinar yAttrs.put ("usercert ificate",  Boolean.TR UE);     / /2.5.4.36
  100           de faultBinar yAttrs.put ("cacertif icate", Bo olean.TRUE );       / /2.5.4.37
  101           de faultBinar yAttrs.put ("certific aterevocat ionlist",  Boolean.TR UE);
  102                                                       // 2.5.4.39
  103           de faultBinar yAttrs.put ("authorit yrevocatio nlist", Bo olean.TRUE ); //2.5.4 .38
  104           de faultBinar yAttrs.put ("crosscer tificatepa ir", Boole an.TRUE);     //2.5.4 .40
  105           de faultBinar yAttrs.put ("photo",  Boolean.TR UE);   //0 .9.2342.19 200300.100 .1.7
  106           de faultBinar yAttrs.put ("personal signature" , Boolean. TRUE);
  107                                                       // 0.9.2342.1 9200300.10 0.1.53
  108           de faultBinar yAttrs.put ("x500uniq ueidentifi er", Boole an.TRUE);  //2.5.4.45
  109       }
  110  
  111       privat e static f inal Strin g DISCONNE CT_OID = " 1.3.6.1.4. 1.1466.200 36";
  112  
  113  
  114       // --- ---------- ----------  instance  fields --- ---------- ---------- -
  115       boolea n isLdapv3 ;          // Used by  LdapCtx
  116       int re ferenceCou nt = 1;    // Used by  LdapCtx f or check f or sharing
  117  
  118       Connec tion conn;   // Conne ction to s erver; has  reader th read
  119                           // used  by LdapCtx  for Start TLS
  120  
  121       final  private Po olCallback  pcb;
  122       final  private bo olean pool ed;
  123       privat e boolean  authentica teCalled =  false;
  124  
  125       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  126       //
  127       // con structor:  Create an  authentica ted connec tion to se rver
  128       //
  129       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  130  
  131       LdapCl ient(Strin g host, in t port, St ring socke tFactory,
  132           in t connectT imeout, in t readTime out, Outpu tStream tr ace, PoolC allback pc b)
  133           th rows Namin gException  {
  134  
  135           if  (debug >  0)
  136                System.e rr.println ("LdapClie nt: constr uctor call ed " + hos t + ":" +  port );
  137           co nn = new C onnection( this, host , port, so cketFactor y, connect Timeout, r eadTimeout ,
  138                trace);
  139  
  140           th is.pcb = p cb;
  141           po oled = (pc b != null) ;
  142       }
  143  
  144       synchr onized boo lean authe nticateCal led() {
  145           re turn authe nticateCal led;
  146       }
  147  
  148       synchr onized Lda pResult
  149       authen ticate(boo lean initi al, String  name, Obj ect pw, in t version,
  150           St ring authM echanism,  Control[]  ctls,  Has htable<?,? > env)
  151           th rows Namin gException  {
  152  
  153           in t readTime out = conn .readTimeo ut;
  154           co nn.readTim eout = con n.connectT imeout;
  155           Ld apResult r es = null;
  156  
  157           tr y {
  158                authenti cateCalled  = true;
  159  
  160                try {
  161                    ensu reOpen();
  162                } catch  (IOExcepti on e) {
  163                    Nami ngExceptio n ne = new  Communica tionExcept ion();
  164                    ne.s etRootCaus e(e);
  165                    thro w ne;
  166                }
  167  
  168                switch ( version) {
  169                case LDA P_VERSION3 _VERSION2:
  170                case LDA P_VERSION3 :
  171                    isLd apv3 = tru e;
  172                    brea k;
  173                case LDA P_VERSION2 :
  174                    isLd apv3 = fal se;
  175                    brea k;
  176                default:
  177                    thro w new Comm unicationE xception(" Protocol v ersion " +  version +
  178                         " not supp orted");
  179                }
  180  
  181                if (auth Mechanism. equalsIgno reCase("no ne") ||
  182                    auth Mechanism. equalsIgno reCase("an onymous"))  {
  183  
  184                    // P erform LDA P bind if  we are rea uthenticat ing, using  LDAPv2,
  185                    // s upporting  failover t o LDAPv2,  or control s have bee n supplied .
  186                    if ( !initial | |
  187                         (version = = LDAP_VER SION2) ||
  188                         (version = = LDAP_VER SION3_VERS ION2) ||
  189                         ((ctls !=  null) && ( ctls.lengt h > 0))) {
  190                         try {
  191                             // ano nymous bin d; update  name/pw fo r LDAPv2 r etry
  192                             res =  ldapBind(n ame=null,  (byte[])(p w=null), c tls, null,
  193                                 fa lse);
  194                             if (re s.status = = LdapClie nt.LDAP_SU CCESS) {
  195                                 co nn.setBoun d();
  196                             }
  197                         } catch (I OException  e) {
  198                             Naming Exception  ne =
  199                                 ne w Communic ationExcep tion("anon ymous bind  failed: "  +
  200                                 co nn.host +  ":" + conn .port);
  201                             ne.set RootCause( e);
  202                             throw  ne;
  203                         }
  204                    } el se {
  205                         // Skip LD AP bind fo r LDAPv3 a nonymous b ind
  206                         res = new  LdapResult ();
  207                         res.status  = LdapCli ent.LDAP_S UCCESS;
  208                    }
  209                } else i f (authMec hanism.equ alsIgnoreC ase("simpl e")) {
  210                    // s imple auth entication
  211                    byte [] encoded Pw = null;
  212                    try  {
  213                         encodedPw  = encodePa ssword(pw,  isLdapv3) ;
  214                         res = ldap Bind(name,  encodedPw , ctls, nu ll, false) ;
  215                         if (res.st atus == Ld apClient.L DAP_SUCCES S) {
  216                             conn.s etBound();
  217                         }
  218                    } ca tch (IOExc eption e)  {
  219                         NamingExce ption ne =
  220                             new Co mmunicatio nException ("simple b ind failed : " +
  221                                 co nn.host +  ":" + conn .port);
  222                         ne.setRoot Cause(e);
  223                         throw ne;
  224                    } fi nally {
  225                         // If pw w as copied  to a new a rray, clea r that arr ay as
  226                         // a secur ity precau tion.
  227                         if (encode dPw != pw  && encoded Pw != null ) {
  228                             for (i nt i = 0;  i < encode dPw.length ; i++) {
  229                                 en codedPw[i]  = 0;
  230                             }
  231                         }
  232                    }
  233                } else i f (isLdapv 3) {
  234                    // S ASL authen tication
  235                    try  {
  236                         res = Ldap Sasl.saslB ind(this,  conn, conn .host, nam e, pw,
  237                             authMe chanism, e nv, ctls);
  238                         if (res.st atus == Ld apClient.L DAP_SUCCES S) {
  239                             conn.s etBound();
  240                         }
  241                    } ca tch (IOExc eption e)  {
  242                         NamingExce ption ne =
  243                             new Co mmunicatio nException ("SASL bin d failed:  " +
  244                             conn.h ost + ":"  + conn.por t);
  245                         ne.setRoot Cause(e);
  246                         throw ne;
  247                    }
  248                } else {
  249                    thro w new Auth entication NotSupport edExceptio n(authMech anism);
  250                }
  251  
  252                //
  253                // re-tr y login us ing v2 if  failing ov er
  254                //
  255                if (init ial &&
  256                    (res .status ==  LdapClien t.LDAP_PRO TOCOL_ERRO R) &&
  257                    (ver sion == Ld apClient.L DAP_VERSIO N3_VERSION 2) &&
  258                    (aut hMechanism .equalsIgn oreCase("n one") ||
  259                         authMechan ism.equals IgnoreCase ("anonymou s") ||
  260                         authMechan ism.equals IgnoreCase ("simple") )) {
  261  
  262                    byte [] encoded Pw = null;
  263                    try  {
  264                         isLdapv3 =  false;
  265                         encodedPw  = encodePa ssword(pw,  false);
  266                         res = ldap Bind(name,  encodedPw , ctls, nu ll, false) ;
  267                         if (res.st atus == Ld apClient.L DAP_SUCCES S) {
  268                             conn.s etBound();
  269                         }
  270                    } ca tch (IOExc eption e)  {
  271                         NamingExce ption ne =
  272                             new Co mmunicatio nException (authMecha nism + ":"  +
  273                                 co nn.host +      ":" +  conn.port) ;
  274                         ne.setRoot Cause(e);
  275                         throw ne;
  276                    } fi nally {
  277                         // If pw w as copied  to a new a rray, clea r that arr ay as
  278                         // a secur ity precau tion.
  279                         if (encode dPw != pw  && encoded Pw != null ) {
  280                             for (i nt i = 0;  i < encode dPw.length ; i++) {
  281                                 en codedPw[i]  = 0;
  282                             }
  283                         }
  284                    }
  285                }
  286  
  287                // princ ipal name  not found
  288                // (map  NameNotFou ndExceptio n to Authe nticationE xception)
  289                // %%% T his is a w orkaround  for Netsca pe servers  returning
  290                // %%% n o such obj ect when t he princip al name is  not found
  291                // %%% N ote that w hen this w orkaround  is applied , it does  not allow
  292                // %%% r esponse co ntrols to  be recorde d by the c alling con text
  293                if (res. status ==  LdapClient .LDAP_NO_S UCH_OBJECT ) {
  294                    thro w new Auth entication Exception(
  295                         getErrorMe ssage(res. status, re s.errorMes sage));
  296                }
  297                conn.set V3(isLdapv 3);
  298                return r es;
  299           }  finally {
  300                conn.rea dTimeout =  readTimeo ut;
  301           }
  302       }
  303  
  304       /**
  305        * Sen ds an LDAP  Bind requ est.
  306        * Can not be pri vate; call ed by Ldap Sasl
  307        * @pa ram dn The  possibly  null DN to  use in th e BIND req uest. null  if anonym ous.
  308        * @pa ram toServ er The pos sibly null  array of  bytes to s end to the  server.
  309        * @pa ram auth T he authent ication me chanism
  310        *
  311        */
  312       synchr onized pub lic LdapRe sult ldapB ind(String  dn, byte[ ]toServer,
  313           Co ntrol[] bi ndCtls, St ring auth,  boolean p auseAfterR eceipt)
  314           th rows java. io.IOExcep tion, Nami ngExceptio n {
  315  
  316           en sureOpen() ;
  317  
  318           //  flush out standing r equests
  319           co nn.abandon Outstandin gReqs(null );
  320  
  321           Be rEncoder b er = new B erEncoder( );
  322           in t curMsgId  = conn.ge tMsgId();
  323           Ld apResult r es = new L dapResult( );
  324           re s.status =  LDAP_OPER ATIONS_ERR OR;
  325  
  326           //
  327           //  build the  bind requ est.
  328           //
  329           be r.beginSeq (Ber.ASN_S EQUENCE |  Ber.ASN_CO NSTRUCTOR) ;
  330                ber.enco deInt(curM sgId);
  331                ber.begi nSeq(LdapC lient.LDAP _REQ_BIND) ;
  332                    ber. encodeInt( isLdapv3 ?  LDAP_VERS ION3 : LDA P_VERSION2 );
  333                    ber. encodeStri ng(dn, isL dapv3);
  334  
  335                    // i f authenti cation mec hanism spe cified, it  is SASL
  336                    if ( auth != nu ll) {
  337                         ber.beginS eq(Ber.ASN _CONTEXT |  Ber.ASN_C ONSTRUCTOR  | 3);
  338                             ber.en codeString (auth, isL dapv3);     // SASL m echanism
  339                             if (to Server !=  null) {
  340                                 be r.encodeOc tetString( toServer,
  341                                      Ber.ASN_ OCTET_STR) ;
  342                             }
  343                         ber.endSeq ();
  344                    } el se {
  345                         if (toServ er != null ) {
  346                             ber.en codeOctetS tring(toSe rver, Ber. ASN_CONTEX T);
  347                         } else {
  348                             ber.en codeOctetS tring(null , Ber.ASN_ CONTEXT, 0 , 0);
  349                         }
  350                    }
  351                ber.endS eq();
  352  
  353                // Encod e controls
  354                if (isLd apv3) {
  355                    enco deControls (ber, bind Ctls);
  356                }
  357           be r.endSeq() ;
  358  
  359           Ld apRequest  req = conn .writeRequ est(ber, c urMsgId, p auseAfterR eceipt);
  360           if  (toServer  != null)  {
  361                ber.rese t();         // clear  internall y-stored p assword
  362           }
  363  
  364           //  Read repl y
  365           Be rDecoder r ber = conn .readReply (req);
  366  
  367           rb er.parseSe q(null);     // init  seq
  368           rb er.parseIn t();         // msg i d
  369           if  (rber.par seByte() ! =  LDAP_RE P_BIND) {
  370                return r es;
  371           }
  372  
  373           rb er.parseLe ngth();
  374           pa rseResult( rber, res,  isLdapv3) ;
  375  
  376           //  handle se rver's cre dentials ( if present )
  377           if  (isLdapv3  &&
  378                (rber.by tesLeft()  > 0) &&
  379                (rber.pe ekByte() = = (Ber.ASN _CONTEXT |  7))) {
  380                res.serv erCreds =  rber.parse OctetStrin g((Ber.ASN _CONTEXT |  7), null) ;
  381           }
  382  
  383           re s.resContr ols = isLd apv3 ? par seControls (rber) : n ull;
  384  
  385           co nn.removeR equest(req );
  386           re turn res;
  387       }
  388  
  389       /**
  390        * Det ermines wh ether SASL  encryptio n/integrit y is in pr ogress.
  391        * Thi s check is  made prio r to reaut henticatio n. You can not reauth enticate
  392        * ove r an encry pted/integ rity-prote cted SASL  channel. Y ou must
  393        * clo se the cha nnel and o pen a new  one.
  394        */
  395       boolea n usingSas lStreams()  {
  396           re turn (conn .inStream  instanceof  SaslInput Stream);
  397       }
  398  
  399       synchr onized voi d incRefCo unt() {
  400           ++ referenceC ount;
  401           if  (debug >  1) {
  402                System.e rr.println ("LdapClie nt.incRefC ount: " +  referenceC ount + " "  + this);
  403           }
  404  
  405       }
  406  
  407       /**
  408        * Ret urns the e ncoded pas sword.
  409        */
  410       privat e static b yte[] enco dePassword (Object pw , boolean  v3) throws  IOExcepti on {
  411  
  412           if  (pw insta nceof char []) {
  413                pw = new  String((c har[])pw);
  414           }
  415  
  416           if  (pw insta nceof Stri ng) {
  417                if (v3)  {
  418                    retu rn ((Strin g)pw).getB ytes("UTF8 ");
  419                } else {
  420                    retu rn ((Strin g)pw).getB ytes("8859 _1");
  421                }
  422           }  else {
  423                return ( byte[])pw;
  424           }
  425       }
  426  
  427       synchr onized voi d close(Co ntrol[] re qCtls, boo lean hardC lose) {
  428           -- referenceC ount;
  429  
  430           if  (debug >  1) {
  431                System.e rr.println ("LdapClie nt: " + th is);
  432                System.e rr.println ("LdapClie nt: close( ) called:  " + refere nceCount);
  433                (new Thr owable()). printStack Trace();
  434           }
  435  
  436           if  (referenc eCount <=  0 && conn  != null) {
  437                if (debu g > 0) Sys tem.err.pr intln("Lda pClient: c losed conn ection " +  this);
  438                if (!poo led) {
  439                    // N ot being p ooled; con tinue with  closing
  440                    conn .cleanup(r eqCtls, fa lse);
  441                    conn  = null;
  442                } else {
  443                    // P ooled
  444  
  445                    // I s this a r eal close  or a reque st to retu rn conn to  pool
  446                    if ( hardClose)  {
  447                         conn.clean up(reqCtls , false);
  448                         conn = nul l;
  449                         pcb.remove PooledConn ection(thi s);
  450                    } el se {
  451                         pcb.releas ePooledCon nection(th is);
  452                    }
  453                }
  454           }
  455       }
  456  
  457       // NOT E: Should  NOT be syn chronized  otherwise  won't be a ble to clo se
  458       privat e void for ceClose(bo olean clea nPool) {
  459           re ferenceCou nt = 0; //  force clo sing of co nnection
  460  
  461           if  (debug >  1) {
  462                System.e rr.println ("LdapClie nt: forceC lose() of  " + this);
  463           }
  464  
  465           if  (conn !=  null) {
  466                if (debu g > 0) Sys tem.err.pr intln(
  467                    "Lda pClient: f orced clos e of conne ction " +  this);
  468                conn.cle anup(null,  false);
  469                conn = n ull;
  470  
  471                if (clea nPool) {
  472                    pcb. removePool edConnecti on(this);
  473                }
  474           }
  475       }
  476  
  477       protec ted void f inalize()  {
  478           if  (debug >  0) System. err.printl n("LdapCli ent: final ize " + th is);
  479           fo rceClose(p ooled);
  480       }
  481  
  482       /*
  483        * Use d by conne ction pool ing to clo se physica l connecti on.
  484        */
  485       synchr onized pub lic void c loseConnec tion() {
  486           fo rceClose(f alse); //  this is a  pool callb ack so no  need to cl ean pool
  487       }
  488  
  489       /**
  490        * Cal led by Con nection.cl eanup(). L dapClient  should
  491        * not ify any un solicited  listeners  and removi ng itself  from any p ool.
  492        * Thi s is almos t like for ceClose(),  except it  doesn't c all
  493        * Con nection.cl eanup() (b ecause thi s is calle d from cle anup()).
  494        */
  495       void p rocessConn ectionClos ure() {
  496           //  Notify li steners
  497           if  (unsolici ted.size()  > 0) {
  498                String m sg;
  499                if (conn  != null)  {
  500                    msg  = conn.hos t + ":" +  conn.port  + " connec tion close d";
  501                } else {
  502                    msg  = "Connect ion closed ";
  503                }
  504                notifyUn solicited( new Commun icationExc eption(msg ));
  505           }
  506  
  507           //  Remove fr om pool
  508           if  (pooled)  {
  509                pcb.remo vePooledCo nnection(t his);
  510           }
  511       }
  512  
  513       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  514       //
  515       // LDA P search.  also inclu des method s to encod e rfc 1558  compliant  filters
  516       //
  517       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  518  
  519       static  final int  SCOPE_BAS E_OBJECT =  0;
  520       static  final int  SCOPE_ONE _LEVEL = 1 ;
  521       static  final int  SCOPE_SUB TREE = 2;
  522  
  523       LdapRe sult searc h(String d n, int sco pe, int de ref, int s izeLimit,
  524                           int time Limit, boo lean attrs Only, Stri ng attrs[] ,
  525                           String f ilter, int  batchSize , Control[ ] reqCtls,
  526                           Hashtabl e<String,  Boolean> b inaryAttrs ,
  527                           boolean  waitFirstR eply, int  replyQueue Capacity)
  528           th rows IOExc eption, Na mingExcept ion {
  529  
  530           en sureOpen() ;
  531  
  532           Ld apResult r es = new L dapResult( );
  533  
  534           Be rEncoder b er = new B erEncoder( );
  535           in t curMsgId  = conn.ge tMsgId();
  536  
  537                ber.begi nSeq(Ber.A SN_SEQUENC E | Ber.AS N_CONSTRUC TOR);
  538                    ber. encodeInt( curMsgId);
  539                    ber. beginSeq(L DAP_REQ_SE ARCH);
  540                         ber.encode String(dn  == null ?  "" : dn, i sLdapv3);
  541                         ber.encode Int(scope,  LBER_ENUM ERATED);
  542                         ber.encode Int(deref,  LBER_ENUM ERATED);
  543                         ber.encode Int(sizeLi mit);
  544                         ber.encode Int(timeLi mit);
  545                         ber.encode Boolean(at trsOnly);
  546                         Filter.enc odeFilterS tring(ber,  filter, i sLdapv3);
  547                         ber.beginS eq(Ber.ASN _SEQUENCE  | Ber.ASN_ CONSTRUCTO R);
  548                             ber.en codeString Array(attr s, isLdapv 3);
  549                         ber.endSeq ();
  550                    ber. endSeq();
  551                    if ( isLdapv3)  encodeCont rols(ber,  reqCtls);
  552                ber.endS eq();
  553  
  554            L dapRequest  req =
  555                    conn .writeRequ est(ber, c urMsgId, f alse, repl yQueueCapa city);
  556  
  557            r es.msgId =  curMsgId;
  558            r es.status  = LdapClie nt.LDAP_SU CCESS; //o ptimistic
  559            i f (waitFir stReply) {
  560                 // get  first repl y
  561                 res = g etSearchRe ply(req, b atchSize,  res, binar yAttrs);
  562            }
  563            r eturn res;
  564       }
  565  
  566       /*
  567        * Aba ndon the s earch oper ation and  remove it  from the m essage que ue.
  568        */
  569       void c learSearch Reply(Ldap Result res , Control[ ] ctls) {
  570           if  (res != n ull && con n != null)  {
  571  
  572                // Only  send an LD AP abandon  operation  when clea ring the s earch
  573                // reply  from a on e-level or  subtree s earch.
  574                LdapRequ est req =  conn.findR equest(res .msgId);
  575                if (req  == null) {
  576                    retu rn;
  577                }
  578  
  579                // OK if  req got r emoved aft er check;  double rem oval attem pt
  580                // but o therwise n o harm don e
  581  
  582                // Send  an LDAP ab andon only  if the se arch opera tion has n ot yet
  583                // compl eted.
  584                if (req. hasSearchC ompleted() ) {
  585                    conn .removeReq uest(req);
  586                } else {
  587                    conn .abandonRe quest(req,  ctls);
  588                }
  589           }
  590       }
  591  
  592       /*
  593        * Ret rieve the  next batch  of entrie s and/or r eferrals.
  594        */
  595       LdapRe sult getSe archReply( int batchS ize, LdapR esult res,
  596           Ha shtable<St ring, Bool ean> binar yAttrs) th rows IOExc eption, Na mingExcept ion {
  597  
  598           en sureOpen() ;
  599  
  600           Ld apRequest  req;
  601  
  602           if  ((req = c onn.findRe quest(res. msgId)) ==  null) {
  603                return n ull;
  604           }
  605  
  606           re turn getSe archReply( req, batch Size, res,  binaryAtt rs);
  607       }
  608  
  609       privat e LdapResu lt getSear chReply(Ld apRequest  req,
  610           in t batchSiz e, LdapRes ult res, H ashtable<S tring, Boo lean> bina ryAttrs)
  611           th rows IOExc eption, Na mingExcept ion {
  612  
  613           if  (batchSiz e == 0)
  614                batchSiz e = Intege r.MAX_VALU E;
  615  
  616           if  (res.entr ies != nul l) {
  617                res.entr ies.setSiz e(0); // c lear the ( previous)  set of ent ries
  618           }  else {
  619                res.entr ies =
  620                    new  Vector<>(b atchSize = = Integer. MAX_VALUE  ? 32 : bat chSize);
  621           }
  622  
  623           if  (res.refe rrals != n ull) {
  624                res.refe rrals.setS ize(0); //  clear the  (previous ) set of r eferrals
  625           }
  626  
  627           Be rDecoder r eplyBer;     // Decod er for res ponse
  628           in t seq;                  // Reque st id
  629  
  630           At tributes l attrs;       // Attri bute set r ead from r esponse
  631           At tribute la ;            // Attri bute read  from respo nse
  632           St ring DN;                // DN re ad from re sponse
  633           Ld apEntry le ;            // LDAP  entry repr esenting r esponse
  634           in t[] seqlen ;            // Holde r for resp onse lengt h
  635           in t endseq;               // Posit ion of end  of respon se
  636  
  637           fo r (int i =  0; i < ba tchSize;)  {
  638                replyBer  = conn.re adReply(re q);
  639  
  640                //
  641                // proce ss search  reply
  642                //
  643                replyBer .parseSeq( null);                      // i nit seq
  644                replyBer .parseInt( );                          // r eq id
  645                seq = re plyBer.par seSeq(null );
  646  
  647                if (seq  == LDAP_RE P_SEARCH)  {
  648  
  649                    // h andle LDAP v3 search  entries
  650                    latt rs = new B asicAttrib utes(caseI gnore);
  651                    DN =  replyBer. parseStrin g(isLdapv3 );
  652                    le =  new LdapE ntry(DN, l attrs);
  653                    seql en = new i nt[1];
  654  
  655                    repl yBer.parse Seq(seqlen );
  656                    ends eq = reply Ber.getPar sePosition () + seqle n[0];
  657                    whil e ((replyB er.getPars ePosition( ) < endseq ) &&
  658                         (replyBer. bytesLeft( ) > 0)) {
  659                         la = parse Attribute( replyBer,  binaryAttr s);
  660                         lattrs.put (la);
  661                    }
  662                    le.r espCtls =  isLdapv3 ?  parseCont rols(reply Ber) : nul l;
  663  
  664                    res. entries.ad dElement(l e);
  665                    i++;
  666  
  667                } else i f ((seq ==  LDAP_REP_ SEARCH_REF ) && isLda pv3) {
  668  
  669                    // h andle LDAP v3 search  reference
  670                    Vect or<String>  URLs = ne w Vector<> (4);
  671  
  672                    // % %% Althoug h not stri ctly corre ct, some L DAP server s
  673                    //      encode  the SEQUEN CE OF tag  in the Sea rchResultR ef
  674                    if ( replyBer.p eekByte()  ==
  675                         (Ber.ASN_S EQUENCE |  Ber.ASN_CO NSTRUCTOR) ) {
  676                         replyBer.p arseSeq(nu ll);
  677                    }
  678  
  679                    whil e ((replyB er.bytesLe ft() > 0)  &&
  680                         (replyBer. peekByte()  == Ber.AS N_OCTET_ST R)) {
  681  
  682                         URLs.addEl ement(repl yBer.parse String(isL dapv3));
  683                    }
  684  
  685                    if ( res.referr als == nul l) {
  686                         res.referr als = new  Vector<>(4 );
  687                    }
  688                    res. referrals. addElement (URLs);
  689                    res. resControl s = isLdap v3 ? parse Controls(r eplyBer) :  null;
  690  
  691                    // S ave referr al and con tinue to g et next se arch resul t
  692  
  693                } else i f (seq ==  LDAP_REP_E XTENSION)  {
  694  
  695                    pars eExtRespon se(replyBe r, res); / /%%% ignor e for now
  696  
  697                } else i f (seq ==  LDAP_REP_R ESULT) {
  698  
  699                    pars eResult(re plyBer, re s, isLdapv 3);
  700                    res. resControl s = isLdap v3 ? parse Controls(r eplyBer) :  null;
  701  
  702                    conn .removeReq uest(req);
  703                    retu rn res;      // Done  with searc h
  704                }
  705           }
  706  
  707           re turn res;
  708       }
  709  
  710       privat e Attribut e parseAtt ribute(Ber Decoder be r,
  711                                           Has htable<Str ing, Boole an> binary Attrs)
  712           th rows IOExc eption {
  713  
  714           in t len[] =  new int[1] ;
  715           in t seq = be r.parseSeq (null);
  716           St ring attri d = ber.pa rseString( isLdapv3);
  717           bo olean hasB inaryValue s = isBina ryValued(a ttrid, bin aryAttrs);
  718           At tribute la  = new Lda pAttribute (attrid);
  719  
  720           if  ((seq = b er.parseSe q(len)) ==  LBER_SET)  {
  721                int attr len = len[ 0];
  722                while (b er.bytesLe ft() > 0 & & attrlen  > 0) {
  723                    try  {
  724                         attrlen -=  parseAttr ibuteValue (ber, la,  hasBinaryV alues);
  725                    } ca tch (IOExc eption ex)  {
  726                         ber.seek(a ttrlen);
  727                         break;
  728                    }
  729                }
  730           }  else {
  731                // Skip  the rest o f the sequ ence becau se it is n ot what we  want
  732                ber.seek (len[0]);
  733           }
  734           re turn la;
  735       }
  736  
  737       //
  738       // ret urns numbe r of bytes  that were  parsed. A dds the va lues to at tr
  739       //
  740       privat e int pars eAttribute Value(BerD ecoder ber , Attribut e la,
  741           bo olean hasB inaryValue s) throws  IOExceptio n {
  742  
  743           in t len[] =  new int[1] ;
  744  
  745           if  (hasBinar yValues) {
  746                la.add(b er.parseOc tetString( ber.peekBy te(), len) );
  747           }  else {
  748                la.add(b er.parseSt ringWithTa g(
  749                                          Ber. ASN_SIMPLE _STRING, i sLdapv3, l en));
  750           }
  751           re turn len[0 ];
  752       }
  753  
  754       privat e boolean  isBinaryVa lued(Strin g attrid,
  755                                         Hasht able<Strin g, Boolean > binaryAt trs) {
  756           St ring id =  attrid.toL owerCase(L ocale.ENGL ISH);
  757  
  758           re turn ((id. indexOf("; binary") ! = -1) ||
  759                defaultB inaryAttrs .containsK ey(id) ||
  760                ((binary Attrs != n ull) && (b inaryAttrs .containsK ey(id))));
  761       }
  762  
  763       // pac kage entry  point; us ed by Conn ection
  764       static  void pars eResult(Be rDecoder r eplyBer, L dapResult  res,
  765                boolean  isLdapv3)  throws IOE xception {
  766  
  767           re s.status =  replyBer. parseEnume ration();
  768           re s.matchedD N = replyB er.parseSt ring(isLda pv3);
  769           re s.errorMes sage = rep lyBer.pars eString(is Ldapv3);
  770  
  771           //  handle LD APv3 refer rals (if p resent)
  772           if  (isLdapv3  &&
  773                (replyBe r.bytesLef t() > 0) & &
  774                (replyBe r.peekByte () == LDAP _REP_REFER RAL)) {
  775  
  776                Vector<S tring> URL s = new Ve ctor<>(4);
  777                int[] se qlen = new  int[1];
  778  
  779                replyBer .parseSeq( seqlen);
  780                int ends eq = reply Ber.getPar sePosition () + seqle n[0];
  781                while (( replyBer.g etParsePos ition() <  endseq) &&
  782                    (rep lyBer.byte sLeft() >  0)) {
  783  
  784                    URLs .addElemen t(replyBer .parseStri ng(isLdapv 3));
  785                }
  786  
  787                if (res. referrals  == null) {
  788                    res. referrals  = new Vect or<>(4);
  789                }
  790                res.refe rrals.addE lement(URL s);
  791           }
  792       }
  793  
  794       // pac kage entry  point; us ed by Conn ection
  795       static  Vector<Co ntrol> par seControls (BerDecode r replyBer ) throws I OException  {
  796  
  797           //  handle LD APv3 contr ols (if pr esent)
  798           if  ((replyBe r.bytesLef t() > 0) & & (replyBe r.peekByte () == LDAP _CONTROLS) ) {
  799                Vector<C ontrol> ct ls = new V ector<>(4) ;
  800                String c ontrolOID;
  801                boolean  criticalit y = false;  // defaul t
  802                byte[] c ontrolValu e = null;   // option al
  803                int[] se qlen = new  int[1];
  804  
  805                replyBer .parseSeq( seqlen);
  806                int ends eq = reply Ber.getPar sePosition () + seqle n[0];
  807                while (( replyBer.g etParsePos ition() <  endseq) &&
  808                    (rep lyBer.byte sLeft() >  0)) {
  809  
  810                    repl yBer.parse Seq(null);
  811                    cont rolOID = r eplyBer.pa rseString( true);
  812  
  813                    if ( (replyBer. bytesLeft( ) > 0) &&
  814                         (replyBer. peekByte()  == Ber.AS N_BOOLEAN) ) {
  815                         criticalit y = replyB er.parseBo olean();
  816                    }
  817                    if ( (replyBer. bytesLeft( ) > 0) &&
  818                         (replyBer. peekByte()  == Ber.AS N_OCTET_ST R)) {
  819                         controlVal ue =
  820                             replyB er.parseOc tetString( Ber.ASN_OC TET_STR, n ull);
  821                    }
  822                    if ( controlOID  != null)  {
  823                         ctls.addEl ement(
  824                             new Ba sicControl (controlOI D, critica lity, cont rolValue)) ;
  825                    }
  826                }
  827                return c tls;
  828           }  else {
  829                return n ull;
  830           }
  831       }
  832  
  833       privat e void par seExtRespo nse(BerDec oder reply Ber, LdapR esult res)
  834           th rows IOExc eption {
  835  
  836           pa rseResult( replyBer,  res, isLda pv3);
  837  
  838           if  ((replyBe r.bytesLef t() > 0) & &
  839                (replyBe r.peekByte () == LDAP _REP_EXT_O ID)) {
  840                res.exte nsionId =
  841                    repl yBer.parse StringWith Tag(LDAP_R EP_EXT_OID , isLdapv3 , null);
  842           }
  843           if  ((replyBe r.bytesLef t() > 0) & &
  844                (replyBe r.peekByte () == LDAP _REP_EXT_V AL)) {
  845                res.exte nsionValue  =
  846                    repl yBer.parse OctetStrin g(LDAP_REP _EXT_VAL,  null);
  847           }
  848  
  849           re s.resContr ols = pars eControls( replyBer);
  850       }
  851  
  852       //
  853       // Enc ode LDAPv3  controls
  854       //
  855       static  void enco deControls (BerEncode r ber, Con trol[] req Ctls)
  856           th rows IOExc eption {
  857  
  858           if  ((reqCtls  == null)  || (reqCtl s.length = = 0)) {
  859                return;
  860           }
  861  
  862           by te[] contr olVal;
  863  
  864           be r.beginSeq (LdapClien t.LDAP_CON TROLS);
  865  
  866                for (int  i = 0; i  < reqCtls. length; i+ +) {
  867                    ber. beginSeq(B er.ASN_SEQ UENCE | Be r.ASN_CONS TRUCTOR);
  868                         ber.encode String(req Ctls[i].ge tID(), tru e); // con trol OID
  869                         if (reqCtl s[i].isCri tical()) {
  870                             ber.en codeBoolea n(true); / / critical  control
  871                         }
  872                         if ((contr olVal = re qCtls[i].g etEncodedV alue()) !=  null) {
  873                             ber.en codeOctetS tring(cont rolVal, Be r.ASN_OCTE T_STR);
  874                         }
  875                    ber. endSeq();
  876                }
  877           be r.endSeq() ;
  878       }
  879  
  880       /**
  881        * Rea ds the nex t reply co rrespondin g to msgId , outstand ing on req uestBer.
  882        * Pro cesses the  result an d any cont rols.
  883        */
  884       privat e LdapResu lt process Reply(Ldap Request re q,
  885           Ld apResult r es, int re sponseType ) throws I OException , NamingEx ception {
  886  
  887           Be rDecoder r ber = conn .readReply (req);
  888  
  889           rb er.parseSe q(null);     // init  seq
  890           rb er.parseIn t();         // msg i d
  891           if  (rber.par seByte() ! =  respons eType) {
  892                return r es;
  893           }
  894  
  895           rb er.parseLe ngth();
  896           pa rseResult( rber, res,  isLdapv3) ;
  897           re s.resContr ols = isLd apv3 ? par seControls (rber) : n ull;
  898  
  899           co nn.removeR equest(req );
  900  
  901           re turn res;      // Don e with ope ration
  902       }
  903  
  904       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  905       //
  906       // LDA P modify:
  907       //  Mo dify the D N dn with  the operat ions on at tributes a ttrs.
  908       //  ie , operatio ns[0] is t he operati on to be p erformed o n
  909       //  at trs[0];
  910       //           dn -  DN to mod ify
  911       //           oper ations - a dd, delete  or replac e
  912       //           attr s - array  of Attribu te
  913       //           reqC tls - arra y of reque st control s
  914       //
  915       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  916  
  917       static  final int  ADD = 0;
  918       static  final int  DELETE =  1;
  919       static  final int  REPLACE =  2;
  920  
  921       LdapRe sult modif y(String d n, int ope rations[],  Attribute  attrs[],
  922                           Control[ ] reqCtls)
  923           th rows IOExc eption, Na mingExcept ion {
  924  
  925           en sureOpen() ;
  926  
  927           Ld apResult r es = new L dapResult( );
  928           re s.status =  LDAP_OPER ATIONS_ERR OR;
  929  
  930           if  (dn == nu ll || oper ations.len gth != att rs.length)
  931                return r es;
  932  
  933           Be rEncoder b er = new B erEncoder( );
  934           in t curMsgId  = conn.ge tMsgId();
  935  
  936           be r.beginSeq (Ber.ASN_S EQUENCE |  Ber.ASN_CO NSTRUCTOR) ;
  937                ber.enco deInt(curM sgId);
  938                ber.begi nSeq(LDAP_ REQ_MODIFY );
  939                    ber. encodeStri ng(dn, isL dapv3);
  940                    ber. beginSeq(B er.ASN_SEQ UENCE | Be r.ASN_CONS TRUCTOR);
  941                         for (int i  = 0; i <  operations .length; i ++) {
  942                             ber.be ginSeq(Ber .ASN_SEQUE NCE | Ber. ASN_CONSTR UCTOR);
  943                                 be r.encodeIn t(operatio ns[i], LBE R_ENUMERAT ED);
  944  
  945                                 //  zero valu es is not  permitted  for the ad d op.
  946                                 if  ((operati ons[i] ==  ADD) && ha sNoValue(a ttrs[i]))  {
  947                                      throw ne w InvalidA ttributeVa lueExcepti on(
  948                                          "'"  + attrs[i] .getID() +  "' has no  values.") ;
  949                                 }  else {
  950                                      encodeAt tribute(be r, attrs[i ]);
  951                                 }
  952                             ber.en dSeq();
  953                         }
  954                    ber. endSeq();
  955                ber.endS eq();
  956                if (isLd apv3) enco deControls (ber, reqC tls);
  957           be r.endSeq() ;
  958  
  959           Ld apRequest  req = conn .writeRequ est(ber, c urMsgId);
  960  
  961           re turn proce ssReply(re q, res, LD AP_REP_MOD IFY);
  962       }
  963  
  964       privat e void enc odeAttribu te(BerEnco der ber, A ttribute a ttr)
  965           th rows IOExc eption, Na mingExcept ion {
  966  
  967           be r.beginSeq (Ber.ASN_S EQUENCE |  Ber.ASN_CO NSTRUCTOR) ;
  968                ber.enco deString(a ttr.getID( ), isLdapv 3);
  969                ber.begi nSeq(Ber.A SN_SEQUENC E | Ber.AS N_CONSTRUC TOR | 1);
  970                    Nami ngEnumerat ion<?> enu m_ = attr. getAll();
  971                    Obje ct val;
  972                    whil e (enum_.h asMore())  {
  973                         val = enum _.next();
  974                         if (val in stanceof S tring) {
  975                             ber.en codeString ((String)v al, isLdap v3);
  976                         } else if  (val insta nceof byte []) {
  977                             ber.en codeOctetS tring((byt e[])val, B er.ASN_OCT ET_STR);
  978                         } else if  (val == nu ll) {
  979                             // no  attribute  value
  980                         } else {
  981                             throw  new Invali dAttribute ValueExcep tion(
  982                                 "M alformed ' " + attr.g etID() + " ' attribut e value");
  983                         }
  984                    }
  985                ber.endS eq();
  986           be r.endSeq() ;
  987       }
  988  
  989       privat e static b oolean has NoValue(At tribute at tr) throws  NamingExc eption {
  990           re turn attr. size() ==  0 || (attr .size() ==  1 && attr .get() ==  null);
  991       }
  992  
  993       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  994       //
  995       // LDA P add
  996       //           Adds  entry to  the Direct ory
  997       //
  998       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  999  
  1000       LdapRe sult add(L dapEntry e ntry, Cont rol[] reqC tls)
  1001           th rows IOExc eption, Na mingExcept ion {
  1002  
  1003           en sureOpen() ;
  1004  
  1005           Ld apResult r es = new L dapResult( );
  1006           re s.status =  LDAP_OPER ATIONS_ERR OR;
  1007  
  1008           if  (entry ==  null || e ntry.DN ==  null)
  1009                return r es;
  1010  
  1011           Be rEncoder b er = new B erEncoder( );
  1012           in t curMsgId  = conn.ge tMsgId();
  1013           At tribute at tr;
  1014  
  1015                ber.begi nSeq(Ber.A SN_SEQUENC E | Ber.AS N_CONSTRUC TOR);
  1016                    ber. encodeInt( curMsgId);
  1017                    ber. beginSeq(L DAP_REQ_AD D);
  1018                         ber.encode String(ent ry.DN, isL dapv3);
  1019                         ber.beginS eq(Ber.ASN _SEQUENCE  | Ber.ASN_ CONSTRUCTO R);
  1020                             Naming Enumeratio n<? extend s Attribut e> enum_ =
  1021                                      entry.at tributes.g etAll();
  1022                             while  (enum_.has More()) {
  1023                                 at tr = enum_ .next();
  1024  
  1025                                 //  zero valu es is not  permitted
  1026                                 if  (hasNoVal ue(attr))  {
  1027                                      throw ne w InvalidA ttributeVa lueExcepti on(
  1028                                          "'"  + attr.get ID() + "'  has no val ues.");
  1029                                 }  else {
  1030                                      encodeAt tribute(be r, attr);
  1031                                 }
  1032                             }
  1033                         ber.endSeq ();
  1034                    ber. endSeq();
  1035                    if ( isLdapv3)  encodeCont rols(ber,  reqCtls);
  1036                ber.endS eq();
  1037  
  1038           Ld apRequest  req = conn .writeRequ est(ber, c urMsgId);
  1039           re turn proce ssReply(re q, res, LD AP_REP_ADD );
  1040       }
  1041  
  1042       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1043       //
  1044       // LDA P delete
  1045       //           dele tes entry  from the D irectory
  1046       //
  1047       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1048  
  1049       LdapRe sult delet e(String D N, Control [] reqCtls )
  1050           th rows IOExc eption, Na mingExcept ion {
  1051  
  1052           en sureOpen() ;
  1053  
  1054           Ld apResult r es = new L dapResult( );
  1055           re s.status =  LDAP_OPER ATIONS_ERR OR;
  1056  
  1057           if  (DN == nu ll)
  1058                return r es;
  1059  
  1060           Be rEncoder b er = new B erEncoder( );
  1061           in t curMsgId  = conn.ge tMsgId();
  1062  
  1063                ber.begi nSeq(Ber.A SN_SEQUENC E | Ber.AS N_CONSTRUC TOR);
  1064                    ber. encodeInt( curMsgId);
  1065                    ber. encodeStri ng(DN, LDA P_REQ_DELE TE, isLdap v3);
  1066                    if ( isLdapv3)  encodeCont rols(ber,  reqCtls);
  1067                ber.endS eq();
  1068  
  1069           Ld apRequest  req = conn .writeRequ est(ber, c urMsgId);
  1070  
  1071           re turn proce ssReply(re q, res, LD AP_REP_DEL ETE);
  1072       }
  1073  
  1074       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1075       //
  1076       // LDA P modrdn
  1077       //  Ch anges the  last eleme nt of DN t o newrdn
  1078       //           dn -  DN to cha nge
  1079       //           newr dn - new R DN to rena me to
  1080       //           dele teoldrdn -  boolean w hether to  delete old  attrs or  not
  1081       //           newS uperior -  new place  to put the  entry in  the tree
  1082       //                           (ignored i f server i s LDAPv2)
  1083       //           reqC tls - arra y of reque st control s
  1084       //
  1085       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1086  
  1087       LdapRe sult moddn (String DN , String n ewrdn, boo lean delet eOldRdn,
  1088                          String ne wSuperior,  Control[]  reqCtls)
  1089           th rows IOExc eption, Na mingExcept ion {
  1090  
  1091           en sureOpen() ;
  1092  
  1093           bo olean chan geSuperior  = (newSup erior != n ull &&
  1094                                        newSup erior.leng th() > 0);
  1095  
  1096           Ld apResult r es = new L dapResult( );
  1097           re s.status =  LDAP_OPER ATIONS_ERR OR;
  1098  
  1099           if  (DN == nu ll || newr dn == null )
  1100                return r es;
  1101  
  1102           Be rEncoder b er = new B erEncoder( );
  1103           in t curMsgId  = conn.ge tMsgId();
  1104  
  1105                ber.begi nSeq(Ber.A SN_SEQUENC E | Ber.AS N_CONSTRUC TOR);
  1106                    ber. encodeInt( curMsgId);
  1107                    ber. beginSeq(L DAP_REQ_MO DRDN);
  1108                         ber.encode String(DN,  isLdapv3) ;
  1109                         ber.encode String(new rdn, isLda pv3);
  1110                         ber.encode Boolean(de leteOldRdn );
  1111                         if(isLdapv 3 && chang eSuperior)  {
  1112                             //Syst em.err.pri ntln("chan gin superi or");
  1113                             ber.en codeString (newSuperi or, LDAP_S UPERIOR_DN , isLdapv3 );
  1114                         }
  1115                    ber. endSeq();
  1116                    if ( isLdapv3)  encodeCont rols(ber,  reqCtls);
  1117                ber.endS eq();
  1118  
  1119  
  1120           Ld apRequest  req = conn .writeRequ est(ber, c urMsgId);
  1121  
  1122           re turn proce ssReply(re q, res, LD AP_REP_MOD RDN);
  1123       }
  1124  
  1125       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1126       //
  1127       // LDA P compare
  1128       //  Co mpare attr ibute->val ue pairs i n dn
  1129       //
  1130       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1131  
  1132       LdapRe sult compa re(String  DN, String  type, Str ing value,  Control[]  reqCtls)
  1133           th rows IOExc eption, Na mingExcept ion {
  1134  
  1135           en sureOpen() ;
  1136  
  1137           Ld apResult r es = new L dapResult( );
  1138           re s.status =  LDAP_OPER ATIONS_ERR OR;
  1139  
  1140           if  (DN == nu ll || type  == null | | value ==  null)
  1141                return r es;
  1142  
  1143           Be rEncoder b er = new B erEncoder( );
  1144           in t curMsgId  = conn.ge tMsgId();
  1145  
  1146                ber.begi nSeq(Ber.A SN_SEQUENC E | Ber.AS N_CONSTRUC TOR);
  1147                    ber. encodeInt( curMsgId);
  1148                    ber. beginSeq(L DAP_REQ_CO MPARE);
  1149                         ber.encode String(DN,  isLdapv3) ;
  1150                         ber.beginS eq(Ber.ASN _SEQUENCE  | Ber.ASN_ CONSTRUCTO R);
  1151                             ber.en codeString (type, isL dapv3);
  1152  
  1153                             // rep lace any e scaped cha racters in  the value
  1154                             byte[]  val = isL dapv3 ?
  1155                                 va lue.getByt es("UTF8")  : value.g etBytes("8 859_1");
  1156                             ber.en codeOctetS tring(
  1157                                 Fi lter.unesc apeFilterV alue(val,  0, val.len gth),
  1158                                 Be r.ASN_OCTE T_STR);
  1159  
  1160                         ber.endSeq ();
  1161                    ber. endSeq();
  1162                    if ( isLdapv3)  encodeCont rols(ber,  reqCtls);
  1163                ber.endS eq();
  1164  
  1165           Ld apRequest  req = conn .writeRequ est(ber, c urMsgId);
  1166  
  1167           re turn proce ssReply(re q, res, LD AP_REP_COM PARE);
  1168       }
  1169  
  1170       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1171       //
  1172       // LDA P extended  operation
  1173       //
  1174       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1175  
  1176       LdapRe sult exten dedOp(Stri ng id, byt e[] reques t, Control [] reqCtls ,
  1177           bo olean paus eAfterRece ipt) throw s IOExcept ion, Namin gException  {
  1178  
  1179           en sureOpen() ;
  1180  
  1181           Ld apResult r es = new L dapResult( );
  1182           re s.status =  LDAP_OPER ATIONS_ERR OR;
  1183  
  1184           if  (id == nu ll)
  1185                return r es;
  1186  
  1187           Be rEncoder b er = new B erEncoder( );
  1188           in t curMsgId  = conn.ge tMsgId();
  1189  
  1190                ber.begi nSeq(Ber.A SN_SEQUENC E | Ber.AS N_CONSTRUC TOR);
  1191                    ber. encodeInt( curMsgId);
  1192                    ber. beginSeq(L DAP_REQ_EX TENSION);
  1193                         ber.encode String(id,
  1194                             Ber.AS N_CONTEXT  | 0, isLda pv3);//[0]
  1195                         if (reques t != null)  {
  1196                             ber.en codeOctetS tring(requ est,
  1197                                 Be r.ASN_CONT EXT | 1);/ /[1]
  1198                         }
  1199                    ber. endSeq();
  1200                    enco deControls (ber, reqC tls); // a lways v3
  1201                ber.endS eq();
  1202  
  1203           Ld apRequest  req = conn .writeRequ est(ber, c urMsgId, p auseAfterR eceipt);
  1204  
  1205           Be rDecoder r ber = conn .readReply (req);
  1206  
  1207           rb er.parseSe q(null);     // init  seq
  1208           rb er.parseIn t();         // msg i d
  1209           if  (rber.par seByte() ! =  LDAP_RE P_EXTENSIO N) {
  1210                return r es;
  1211           }
  1212  
  1213           rb er.parseLe ngth();
  1214           pa rseExtResp onse(rber,  res);
  1215           co nn.removeR equest(req );
  1216  
  1217           re turn res;      // Don e with ope ration
  1218       }
  1219  
  1220  
  1221  
  1222       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1223       //
  1224       // Som e BER defi nitions co nvenient f or LDAP
  1225       //
  1226       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1227  
  1228       static  final int  LDAP_VERS ION3_VERSI ON2 = 32;
  1229       static  final int  LDAP_VERS ION2 = 0x0 2;
  1230       static  final int  LDAP_VERS ION3 = 0x0 3;               // L DAPv3
  1231       static  final int  LDAP_VERS ION = LDAP _VERSION3;
  1232  
  1233       static  final int  LDAP_REF_ FOLLOW = 0 x01;             // f ollow refe rrals
  1234       static  final int  LDAP_REF_ THROW = 0x 02;              // t hrow refer ral ex.
  1235       static  final int  LDAP_REF_ IGNORE = 0 x03;             // i gnore refe rrals
  1236       static  final int  LDAP_REF_ FOLLOW_SCH EME = 0x04 ;     // f ollow refe rrals of t he same sc heme
  1237  
  1238       static  final Str ing LDAP_U RL = "ldap ://";            // L DAPv3
  1239       static  final Str ing LDAPS_ URL = "lda ps://";          // L DAPv3
  1240  
  1241       static  final int  LBER_BOOL EAN = 0x01 ;
  1242       static  final int  LBER_INTE GER = 0x02 ;
  1243       static  final int  LBER_BITS TRING = 0x 03;
  1244       static  final int  LBER_OCTE TSTRING =  0x04;
  1245       static  final int  LBER_NULL  = 0x05;
  1246       static  final int  LBER_ENUM ERATED = 0 x0a;
  1247       static  final int  LBER_SEQU ENCE = 0x3 0;
  1248       static  final int  LBER_SET  = 0x31;
  1249  
  1250       static  final int  LDAP_SUPE RIOR_DN =  0x80;
  1251  
  1252       static  final int  LDAP_REQ_ BIND = 0x6 0;      //  app + con structed
  1253       static  final int  LDAP_REQ_ UNBIND = 0 x42;    //  app + pri mitive
  1254       static  final int  LDAP_REQ_ SEARCH = 0 x63;    //  app + con structed
  1255       static  final int  LDAP_REQ_ MODIFY = 0 x66;    //  app + con structed
  1256       static  final int  LDAP_REQ_ ADD = 0x68 ;       //  app + con structed
  1257       static  final int  LDAP_REQ_ DELETE = 0 x4a;    //  app + pri mitive
  1258       static  final int  LDAP_REQ_ MODRDN = 0 x6c;    //  app + con structed
  1259       static  final int  LDAP_REQ_ COMPARE =  0x6e;   //  app + con structed
  1260       static  final int  LDAP_REQ_ ABANDON =  0x50;   //  app + pri mitive
  1261       static  final int  LDAP_REQ_ EXTENSION  = 0x77; //  app + con structed     (LDAPv3)
  1262  
  1263       static  final int  LDAP_REP_ BIND = 0x6 1;      //  app + con structed |  1
  1264       static  final int  LDAP_REP_ SEARCH = 0 x64;    //  app + con structed |  4
  1265       static  final int  LDAP_REP_ SEARCH_REF  = 0x73;//  app + con structed     (LDAPv3)
  1266       static  final int  LDAP_REP_ RESULT = 0 x65;    //  app + con structed |  5
  1267       static  final int  LDAP_REP_ MODIFY = 0 x67;    //  app + con structed |  7
  1268       static  final int  LDAP_REP_ ADD = 0x69 ;       //  app + con structed |  9
  1269       static  final int  LDAP_REP_ DELETE = 0 x6b;    //  app + pri mitive | b
  1270       static  final int  LDAP_REP_ MODRDN = 0 x6d;    //  app + pri mitive | d
  1271       static  final int  LDAP_REP_ COMPARE =  0x6f;   //  app + pri mitive | f
  1272       static  final int  LDAP_REP_ EXTENSION  = 0x78; //  app + con structed     (LDAPv3)
  1273  
  1274       static  final int  LDAP_REP_ REFERRAL =  0xa3;  //  ctx + con structed     (LDAPv3)
  1275       static  final int  LDAP_REP_ EXT_OID =  0x8a;   //  ctx + pri mitive       (LDAPv3)
  1276       static  final int  LDAP_REP_ EXT_VAL =  0x8b;   //  ctx + pri mitive       (LDAPv3)
  1277  
  1278       // LDA Pv3 Contro ls
  1279  
  1280       static  final int  LDAP_CONT ROLS = 0xa 0;      //  ctx + con structed     (LDAPv3)
  1281       static  final Str ing LDAP_C ONTROL_MAN AGE_DSA_IT  = "2.16.8 40.1.11373 0.3.4.2";
  1282       static  final Str ing LDAP_C ONTROL_PRE FERRED_LAN G = "1.3.6 .1.4.1.146 6.20035";
  1283       static  final Str ing LDAP_C ONTROL_PAG ED_RESULTS  = "1.2.84 0.113556.1 .4.319";
  1284       static  final Str ing LDAP_C ONTROL_SER VER_SORT_R EQ = "1.2. 840.113556 .1.4.473";
  1285       static  final Str ing LDAP_C ONTROL_SER VER_SORT_R ES = "1.2. 840.113556 .1.4.474";
  1286  
  1287       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1288       //
  1289       // ret urn codes
  1290       //
  1291       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1292  
  1293       static  final int  LDAP_SUCC ESS = 0;
  1294       static  final int  LDAP_OPER ATIONS_ERR OR = 1;
  1295       static  final int  LDAP_PROT OCOL_ERROR  = 2;
  1296       static  final int  LDAP_TIME _LIMIT_EXC EEDED = 3;
  1297       static  final int  LDAP_SIZE _LIMIT_EXC EEDED = 4;
  1298       static  final int  LDAP_COMP ARE_FALSE  = 5;
  1299       static  final int  LDAP_COMP ARE_TRUE =  6;
  1300       static  final int  LDAP_AUTH _METHOD_NO T_SUPPORTE D = 7;
  1301       static  final int  LDAP_STRO NG_AUTH_RE QUIRED = 8 ;
  1302       static  final int  LDAP_PART IAL_RESULT S = 9;                    // Sla pd
  1303       static  final int  LDAP_REFE RRAL = 10;                           // LDA Pv3
  1304       static  final int  LDAP_ADMI N_LIMIT_EX CEEDED = 1 1;             // LDA Pv3
  1305       static  final int  LDAP_UNAV AILABLE_CR ITICAL_EXT ENSION = 1 2;  // LDA Pv3
  1306       static  final int  LDAP_CONF IDENTIALIT Y_REQUIRED  = 13;         // LDA Pv3
  1307       static  final int  LDAP_SASL _BIND_IN_P ROGRESS =  14;            // LDA Pv3
  1308       static  final int  LDAP_NO_S UCH_ATTRIB UTE = 16;
  1309       static  final int  LDAP_UNDE FINED_ATTR IBUTE_TYPE  = 17;
  1310       static  final int  LDAP_INAP PROPRIATE_ MATCHING =  18;
  1311       static  final int  LDAP_CONS TRAINT_VIO LATION = 1 9;
  1312       static  final int  LDAP_ATTR IBUTE_OR_V ALUE_EXIST S = 20;
  1313       static  final int  LDAP_INVA LID_ATTRIB UTE_SYNTAX  = 21;
  1314       static  final int  LDAP_NO_S UCH_OBJECT  = 32;
  1315       static  final int  LDAP_ALIA S_PROBLEM  = 33;
  1316       static  final int  LDAP_INVA LID_DN_SYN TAX = 34;
  1317       static  final int  LDAP_IS_L EAF = 35;
  1318       static  final int  LDAP_ALIA S_DEREFERE NCING_PROB LEM = 36;
  1319       static  final int  LDAP_INAP PROPRIATE_ AUTHENTICA TION = 48;
  1320       static  final int  LDAP_INVA LID_CREDEN TIALS = 49 ;
  1321       static  final int  LDAP_INSU FFICIENT_A CCESS_RIGH TS = 50;
  1322       static  final int  LDAP_BUSY  = 51;
  1323       static  final int  LDAP_UNAV AILABLE =  52;
  1324       static  final int  LDAP_UNWI LLING_TO_P ERFORM = 5 3;
  1325       static  final int  LDAP_LOOP _DETECT =  54;
  1326       static  final int  LDAP_NAMI NG_VIOLATI ON = 64;
  1327       static  final int  LDAP_OBJE CT_CLASS_V IOLATION =  65;
  1328       static  final int  LDAP_NOT_ ALLOWED_ON _NON_LEAF  = 66;
  1329       static  final int  LDAP_NOT_ ALLOWED_ON _RDN = 67;
  1330       static  final int  LDAP_ENTR Y_ALREADY_ EXISTS = 6 8;
  1331       static  final int  LDAP_OBJE CT_CLASS_M ODS_PROHIB ITED = 69;
  1332       static  final int  LDAP_AFFE CTS_MULTIP LE_DSAS =  71;            // LDA Pv3
  1333       static  final int  LDAP_OTHE R = 80;
  1334  
  1335       static  final Str ing[] ldap _error_mes sage = {
  1336           "S uccess",                                          // 0
  1337           "O perations  Error",                                // 1
  1338           "P rotocol Er ror",                                  // 2
  1339           "T imelimit E xceeded",                              // 3
  1340           "S izelimit E xceeded",                              // 4
  1341           "C ompare Fal se",                                   // 5
  1342           "C ompare Tru e",                                    // 6
  1343           "A uthenticat ion Method  Not Suppo rted",           // 7
  1344           "S trong Auth entication  Required" ,                // 8
  1345           nu ll,
  1346           "R eferral",                                         // 1 0
  1347           "A dministrat ive Limit  Exceeded",                  // 1 1
  1348           "U navailable  Critical  Extension" ,                // 1 2
  1349           "C onfidentia lity Requi red",                       // 1 3
  1350           "S ASL Bind I n Progress ",                          // 1 4
  1351           nu ll,
  1352           "N o Such Att ribute",                               // 1 6
  1353           "U ndefined A ttribute T ype",                       // 1 7
  1354           "I nappropria te Matchin g",                         // 1 8
  1355           "C onstraint  Violation" ,                           // 1 9
  1356           "A ttribute O r Value Ex ists",                      // 2 0
  1357           "I nvalid Att ribute Syn tax",                       // 2 1
  1358           nu ll,
  1359           nu ll,
  1360           nu ll,
  1361           nu ll,
  1362           nu ll,
  1363           nu ll,
  1364           nu ll,
  1365           nu ll,
  1366           nu ll,
  1367           nu ll,
  1368           "N o Such Obj ect",                                  // 3 2
  1369           "A lias Probl em",                                   // 3 3
  1370           "I nvalid DN  Syntax",                               // 3 4
  1371           nu ll,
  1372           "A lias Deref erencing P roblem",                    // 3 6
  1373           nu ll,
  1374           nu ll,
  1375           nu ll,
  1376           nu ll,
  1377           nu ll,
  1378           nu ll,
  1379           nu ll,
  1380           nu ll,
  1381           nu ll,
  1382           nu ll,
  1383           nu ll,
  1384           "I nappropria te Authent ication",                   // 4 8
  1385           "I nvalid Cre dentials",                             // 4 9
  1386           "I nsufficien t Access R ights",                     // 5 0
  1387           "B usy",                                             // 5 1
  1388           "U navailable ",                                     // 5 2
  1389           "U nwilling T o Perform" ,                           // 5 3
  1390           "L oop Detect ",                                     // 5 4
  1391           nu ll,
  1392           nu ll,
  1393           nu ll,
  1394           nu ll,
  1395           nu ll,
  1396           nu ll,
  1397           nu ll,
  1398           nu ll,
  1399           nu ll,
  1400           "N aming Viol ation",                                // 6 4
  1401           "O bject Clas s Violatio n",                         // 6 5
  1402           "N ot Allowed  On Non-le af",                        // 6 6
  1403           "N ot Allowed  On RDN",                              // 6 7
  1404           "E ntry Alrea dy Exists" ,                           // 6 8
  1405           "O bject Clas s Modifica tions Proh ibited",         // 6 9
  1406           nu ll,
  1407           "A ffects Mul tiple DSAs ",                          // 7 1
  1408           nu ll,
  1409           nu ll,
  1410           nu ll,
  1411           nu ll,
  1412           nu ll,
  1413           nu ll,
  1414           nu ll,
  1415           nu ll,
  1416           "O ther",                                            // 8 0
  1417           nu ll,
  1418           nu ll,
  1419           nu ll,
  1420           nu ll,
  1421           nu ll,
  1422           nu ll,
  1423           nu ll,
  1424           nu ll,
  1425           nu ll,
  1426           nu ll
  1427       };
  1428  
  1429  
  1430       /*
  1431        * Gen erate an e rror messa ge from th e LDAP err or code an d error di agnostic.
  1432        * The  message f ormat is:
  1433        *
  1434        *      "[LDAP: e rror code  <errorCode > - <error Message>]"
  1435        *
  1436        * whe re <errorC ode> is a  numeric er ror code
  1437        * and  <errorMes sage> is a  textual d escription  of the er ror (if av ailable)
  1438        *
  1439        */
  1440       static  String ge tErrorMess age(int er rorCode, S tring erro rMessage)  {
  1441  
  1442           St ring messa ge = "[LDA P: error c ode " + er rorCode;
  1443  
  1444           if  ((errorMe ssage != n ull) && (e rrorMessag e.length()  != 0)) {
  1445  
  1446                // appen d error me ssage from  the serve r
  1447                message  = message  + " - " +  errorMessa ge + "]";
  1448  
  1449           }  else {
  1450  
  1451                // appen d built-in  error mes sage
  1452                try {
  1453                    if ( ldap_error _message[e rrorCode]  != null) {
  1454                         message =  message +  " - " + ld ap_error_m essage[err orCode] +
  1455                                      "]";
  1456                    }
  1457                } catch  (ArrayInde xOutOfBoun dsExceptio n ex) {
  1458                    mess age = mess age + "]";
  1459                }
  1460           }
  1461           re turn messa ge;
  1462       }
  1463  
  1464  
  1465       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1466       //
  1467       // Uns olicited n otificatio n support.
  1468       //
  1469       // An  LdapClient  maintains  a list of  LdapCtx t hat have r egistered
  1470       // for  Unsolicit edNotifica tions. Thi s is a lis t because  a single
  1471       // Lda pClient mi ght be sha red among  multiple c ontexts.
  1472       //
  1473       // Whe n addUnsol icited() i s invoked,  the LdapC tx is adde d to the l ist.
  1474       //
  1475       // Whe n Connecti on receive s an unsol icited not ification  (msgid ==  0),
  1476       // it  invokes Ld apClient.p rocessUnso licited().  processUn solicited( )
  1477       // par ses the Ex tended Res ponse. If  there are  registered  listeners ,
  1478       // Lda pClient cr eates an U nsolicited Notificati on from th e response
  1479       // and  informs e ach LdapCt x to fire  an event f or the not ification.
  1480       // If  it is a DI SCONNECT n otificatio n, the con nection is  closed an d a
  1481       // Nam ingExcepti onEvent is  fired to  the listen ers.
  1482       //
  1483       // Whe n the conn ection is  closed out -of-band l ike this,  the next
  1484       // tim e a method  is invoke d on LdapC lient, an  IOExceptio n is throw n.
  1485       //
  1486       // rem oveUnsolic ited() is  invoked to  remove an  LdapCtx f rom this c lient.
  1487       //
  1488       ////// ////////// ////////// ////////// ////////// ////////// ////////// //////////
  1489       privat e Vector<L dapCtx> un solicited  = new Vect or<>(3);
  1490       void a ddUnsolici ted(LdapCt x ctx) {
  1491           if  (debug >  0) {
  1492                System.e rr.println ("LdapClie nt.addUnso licited" +  ctx);
  1493           }
  1494           un solicited. addElement (ctx);
  1495       }
  1496  
  1497       void r emoveUnsol icited(Lda pCtx ctx)  {
  1498           if  (debug >  0) {
  1499                System.e rr.println ("LdapClie nt.removeU nsolicited " + ctx);
  1500           }
  1501                unsolici ted.remove Element(ct x);
  1502           }
  1503  
  1504       // NOT E: Cannot  be synchro nized beca use this i s called a synchronou sly
  1505       // by  the reader  thread in  Connectio n. Instead , sync on  'unsolicit ed' Vector .
  1506       void p rocessUnso licited(Be rDecoder b er) {
  1507           if  (debug >  0) {
  1508                System.e rr.println ("LdapClie nt.process Unsolicite d");
  1509           }
  1510           tr y {
  1511                // Parse  the respo nse
  1512                LdapResu lt res = n ew LdapRes ult();
  1513  
  1514                ber.pars eSeq(null) ; // init  seq
  1515                ber.pars eInt();               // msg id;  should be  0; ignore d
  1516                if (ber. parseByte( ) != LDAP_ REP_EXTENS ION) {
  1517                    thro w new IOEx ception(
  1518                         "Unsolicit ed Notific ation must  be an Ext ended Resp onse");
  1519                }
  1520                ber.pars eLength();
  1521                parseExt Response(b er, res);
  1522  
  1523                if (DISC ONNECT_OID .equals(re s.extensio nId)) {
  1524                    // f orce closi ng of conn ection
  1525                    forc eClose(poo led);
  1526                }
  1527  
  1528                LdapCtx  first = nu ll;
  1529                Unsolici tedNotific ation noti ce = null;
  1530  
  1531                synchron ized (unso licited) {
  1532                    if ( unsolicite d.size() >  0) {
  1533                         first = un solicited. elementAt( 0);
  1534  
  1535                         // Create  an Unsolic itedNotifi cation usi ng the par sed data
  1536                         // Need a  'ctx' obje ct because  we want t o use the  context's
  1537                         // list of  provider  control fa ctories.
  1538                         notice = n ew Unsolic itedRespon seImpl(
  1539                             res.ex tensionId,
  1540                             res.ex tensionVal ue,
  1541                             res.re ferrals,
  1542                             res.st atus,
  1543                             res.er rorMessage ,
  1544                             res.ma tchedDN,
  1545                             (res.r esControls  != null)  ?
  1546                             first. convertCon trols(res. resControl s) :
  1547                             null);
  1548                    }
  1549                }
  1550  
  1551                if (noti ce != null ) {
  1552                    // F ire Unsoli citedNotif ication ev ents to li steners
  1553                    noti fyUnsolici ted(notice );
  1554  
  1555                    // I f "disconn ect" notif ication,
  1556                    // n otify unso licited li steners vi a NamingEx ception
  1557                    if ( DISCONNECT _OID.equal s(res.exte nsionId))  {
  1558                         notifyUnso licited(
  1559                             new Co mmunicatio nException ("Connecti on closed" ));
  1560                    }
  1561                }
  1562           }  catch (IOE xception e ) {
  1563                NamingEx ception ne  = new Com munication Exception(
  1564                    "Pro blem parsi ng unsolic ited notif ication");
  1565                ne.setRo otCause(e) ;
  1566  
  1567                notifyUn solicited( ne);
  1568  
  1569           }  catch (Nam ingExcepti on e) {
  1570                notifyUn solicited( e);
  1571           }
  1572       }
  1573  
  1574  
  1575       privat e void not ifyUnsolic ited(Objec t e) {
  1576           Ve ctor<LdapC tx> unsoli citedCopy;
  1577           sy nchronized  (unsolici ted) {
  1578                unsolici tedCopy =  new Vector <>(unsolic ited);
  1579                if (e in stanceof N amingExcep tion) {
  1580                    unso licited.se tSize(0);   // no mor e listener s after ex ception
  1581                }
  1582           }
  1583           fo r (int i =  0; i < un solicitedC opy.size() ; i++) {
  1584                unsolici tedCopy.el ementAt(i) .fireUnsol icited(e);
  1585           }
  1586       }
  1587  
  1588       privat e void ens ureOpen()  throws IOE xception {
  1589           if  (conn ==  null || !c onn.useabl e) {
  1590                if (conn  != null & & conn.clo sureReason  != null)  {
  1591                    thro w conn.clo sureReason ;
  1592                } else {
  1593                    thro w new IOEx ception("c onnection  closed");
  1594                }
  1595           }
  1596       }
  1597  
  1598       // pac kage priva te (used b y LdapCtx)
  1599       static  LdapClien t getInsta nce(boolea n usePool,  String ho stname, in t port,
  1600           St ring facto ry, int co nnectTimeo ut, int re adTimeout,  OutputStr eam trace,
  1601           in t version,  String au thMechanis m, Control [] ctls, S tring prot ocol,
  1602           St ring user,  Object pa sswd, Hash table<?,?>  env) thro ws NamingE xception {
  1603  
  1604           if  (usePool)  {
  1605                if (Ldap PoolManage r.isPoolin gAllowed(f actory, tr ace,
  1606                         authMechan ism, proto col, env))  {
  1607                    Ldap Client ans wer = Ldap PoolManage r.getLdapC lient(
  1608                             hostna me, port,  factory, c onnectTime out, readT imeout,
  1609                             trace,  version,  authMechan ism, ctls,  protocol,  user,
  1610                             passwd , env);
  1611                    answ er.referen ceCount =  1;   // al ways one w hen starti ng out
  1612                    retu rn answer;
  1613                }
  1614           }
  1615           re turn new L dapClient( hostname,  port, fact ory, conne ctTimeout,
  1616                                               readTimeou t, trace,  null);
  1617       }
  1618   }