1 /* 2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.jndi.ldap; 27 28 import javax.naming.*; 29 import javax.naming.directory.*; 30 import javax.naming.spi.*; 31 import javax.naming.ldap.*; 32 33 import java.util.Hashtable; 34 import java.util.StringTokenizer; 35 import com.sun.jndi.toolkit.dir.SearchFilter; 36 37 /** 38 * A context for handling referrals. 39 * 40 * @author Vincent Ryan 41 */ 42 final class LdapReferralContext implements DirContext, LdapContext { 43 44 private DirContext refCtx = null; 45 private Name urlName = null; // override the supplied name 46 private String urlAttrs = null; // override attributes 47 private String urlScope = null; // override scope 48 private String urlFilter = null; // override filter 49 50 private LdapReferralException refEx = null; 51 private boolean skipThisReferral = false; 52 private int hopCount = 1; 53 private NamingException previousEx = null; 54 55 @SuppressWarnings("unchecked") // clone() LdapReferralContext(LdapReferralException ex, Hashtable<?,?> env, Control[] connCtls, Control[] reqCtls, String nextName, boolean skipThisReferral, int handleReferrals)56 LdapReferralContext(LdapReferralException ex, 57 Hashtable<?,?> env, 58 Control[] connCtls, 59 Control[] reqCtls, 60 String nextName, 61 boolean skipThisReferral, 62 int handleReferrals) throws NamingException { 63 64 refEx = ex; 65 66 if (this.skipThisReferral = skipThisReferral) { 67 return; // don't create a DirContext for this referral 68 } 69 70 String referral; 71 72 // Make copies of environment and connect controls for our own use. 73 if (env != null) { 74 env = (Hashtable<?,?>) env.clone(); 75 // Remove old connect controls from environment, unless we have new 76 // ones that will override them anyway. 77 if (connCtls == null) { 78 env.remove(LdapCtx.BIND_CONTROLS); 79 } 80 } else if (connCtls != null) { 81 env = new Hashtable<String, Control[]>(5); 82 } 83 if (connCtls != null) { 84 Control[] copiedCtls = new Control[connCtls.length]; 85 System.arraycopy(connCtls, 0, copiedCtls, 0, connCtls.length); 86 // Add copied controls to environment, replacing any old ones. 87 ((Hashtable<? super String, ? super Control[]>)env) 88 .put(LdapCtx.BIND_CONTROLS, copiedCtls); 89 } 90 91 while (true) { 92 try { 93 referral = refEx.getNextReferral(); 94 if (referral == null) { 95 if (previousEx != null) { 96 throw (NamingException)(previousEx.fillInStackTrace()); 97 } else { 98 throw new NamingException( 99 "Illegal encoding: referral is empty"); 100 } 101 } 102 103 } catch (LdapReferralException e) { 104 105 if (handleReferrals == LdapClient.LDAP_REF_THROW) { 106 throw e; 107 } else { 108 refEx = e; 109 continue; 110 } 111 } 112 113 // Create a Reference containing the referral URL. 114 Reference ref = new Reference("javax.naming.directory.DirContext", 115 new StringRefAddr("URL", referral)); 116 117 Object obj; 118 try { 119 obj = NamingManager.getObjectInstance(ref, null, null, env); 120 121 } catch (NamingException e) { 122 123 if (handleReferrals == LdapClient.LDAP_REF_THROW) { 124 throw e; 125 } 126 127 // mask the exception and save it for later 128 previousEx = e; 129 130 // follow another referral 131 continue; 132 133 } catch (Exception e) { 134 NamingException e2 = 135 new NamingException( 136 "problem generating object using object factory"); 137 e2.setRootCause(e); 138 throw e2; 139 } 140 if (obj instanceof DirContext) { 141 refCtx = (DirContext)obj; 142 if (refCtx instanceof LdapContext && reqCtls != null) { 143 ((LdapContext)refCtx).setRequestControls(reqCtls); 144 } 145 initDefaults(referral, nextName); 146 147 break; 148 } else { 149 NamingException ne = new NotContextException( 150 "Cannot create context for: " + referral); 151 ne.setRemainingName((new CompositeName()).add(nextName)); 152 throw ne; 153 } 154 } 155 } 156 initDefaults(String referral, String nextName)157 private void initDefaults(String referral, String nextName) 158 throws NamingException { 159 String urlString; 160 try { 161 // parse URL 162 LdapURL url = new LdapURL(referral); 163 urlString = url.getDN(); 164 urlAttrs = url.getAttributes(); 165 urlScope = url.getScope(); 166 urlFilter = url.getFilter(); 167 168 } catch (NamingException e) { 169 // Not an LDAP URL; use original URL 170 urlString = referral; 171 urlAttrs = urlScope = urlFilter = null; 172 } 173 174 // reuse original name if URL DN is absent 175 if (urlString == null) { 176 urlString = nextName; 177 } else { 178 // concatenate with remaining name if URL DN is present 179 urlString = ""; 180 } 181 182 if (urlString == null) { 183 urlName = null; 184 } else { 185 urlName = urlString.isEmpty() ? new CompositeName() : 186 new CompositeName().add(urlString); 187 } 188 } 189 190 close()191 public void close() throws NamingException { 192 if (refCtx != null) { 193 refCtx.close(); 194 refCtx = null; 195 } 196 refEx = null; 197 } 198 setHopCount(int hopCount)199 void setHopCount(int hopCount) { 200 this.hopCount = hopCount; 201 if ((refCtx != null) && (refCtx instanceof LdapCtx)) { 202 ((LdapCtx)refCtx).setHopCount(hopCount); 203 } 204 } 205 lookup(String name)206 public Object lookup(String name) throws NamingException { 207 return lookup(toName(name)); 208 } 209 lookup(Name name)210 public Object lookup(Name name) throws NamingException { 211 if (skipThisReferral) { 212 throw (NamingException) 213 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 214 } 215 216 return refCtx.lookup(overrideName(name)); 217 } 218 bind(String name, Object obj)219 public void bind(String name, Object obj) throws NamingException { 220 bind(toName(name), obj); 221 } 222 bind(Name name, Object obj)223 public void bind(Name name, Object obj) throws NamingException { 224 if (skipThisReferral) { 225 throw (NamingException) 226 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 227 } 228 229 refCtx.bind(overrideName(name), obj); 230 } 231 rebind(String name, Object obj)232 public void rebind(String name, Object obj) throws NamingException { 233 rebind(toName(name), obj); 234 } 235 rebind(Name name, Object obj)236 public void rebind(Name name, Object obj) throws NamingException { 237 if (skipThisReferral) { 238 throw (NamingException) 239 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 240 } 241 242 refCtx.rebind(overrideName(name), obj); 243 } 244 unbind(String name)245 public void unbind(String name) throws NamingException { 246 unbind(toName(name)); 247 } 248 unbind(Name name)249 public void unbind(Name name) throws NamingException { 250 if (skipThisReferral) { 251 throw (NamingException) 252 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 253 } 254 255 refCtx.unbind(overrideName(name)); 256 } 257 rename(String oldName, String newName)258 public void rename(String oldName, String newName) throws NamingException { 259 rename(toName(oldName), toName(newName)); 260 } 261 rename(Name oldName, Name newName)262 public void rename(Name oldName, Name newName) throws NamingException { 263 if (skipThisReferral) { 264 throw (NamingException) 265 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 266 } 267 268 refCtx.rename(overrideName(oldName), toName(refEx.getNewRdn())); 269 } 270 list(String name)271 public NamingEnumeration<NameClassPair> list(String name) throws NamingException { 272 return list(toName(name)); 273 } 274 275 @SuppressWarnings("unchecked") list(Name name)276 public NamingEnumeration<NameClassPair> list(Name name) throws NamingException { 277 if (skipThisReferral) { 278 throw (NamingException) 279 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 280 } 281 try { 282 NamingEnumeration<NameClassPair> ne = null; 283 284 if (urlScope != null && urlScope.equals("base")) { 285 SearchControls cons = new SearchControls(); 286 cons.setReturningObjFlag(true); 287 cons.setSearchScope(SearchControls.OBJECT_SCOPE); 288 289 ne = (NamingEnumeration) 290 refCtx.search(overrideName(name), "(objectclass=*)", cons); 291 292 } else { 293 ne = refCtx.list(overrideName(name)); 294 } 295 296 refEx.setNameResolved(true); 297 298 // append (referrals from) the exception that generated this 299 // context to the new search results, so that referral processing 300 // can continue 301 ((ReferralEnumeration)ne).appendUnprocessedReferrals(refEx); 302 303 return (ne); 304 305 } catch (LdapReferralException e) { 306 307 // append (referrals from) the exception that generated this 308 // context to the new exception, so that referral processing 309 // can continue 310 311 e.appendUnprocessedReferrals(refEx); 312 throw (NamingException)(e.fillInStackTrace()); 313 314 } catch (NamingException e) { 315 316 // record the exception if there are no remaining referrals 317 if ((refEx != null) && (! refEx.hasMoreReferrals())) { 318 refEx.setNamingException(e); 319 } 320 if ((refEx != null) && 321 (refEx.hasMoreReferrals() || 322 refEx.hasMoreReferralExceptions())) { 323 throw (NamingException) 324 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 325 } else { 326 throw e; 327 } 328 } 329 } 330 listBindings(String name)331 public NamingEnumeration<Binding> listBindings(String name) throws 332 NamingException { 333 return listBindings(toName(name)); 334 } 335 336 @SuppressWarnings("unchecked") listBindings(Name name)337 public NamingEnumeration<Binding> listBindings(Name name) throws 338 NamingException { 339 if (skipThisReferral) { 340 throw (NamingException) 341 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 342 } 343 344 try { 345 NamingEnumeration<Binding> be = null; 346 347 if (urlScope != null && urlScope.equals("base")) { 348 SearchControls cons = new SearchControls(); 349 cons.setReturningObjFlag(true); 350 cons.setSearchScope(SearchControls.OBJECT_SCOPE); 351 352 be = (NamingEnumeration)refCtx.search(overrideName(name), 353 "(objectclass=*)", cons); 354 355 } else { 356 be = refCtx.listBindings(overrideName(name)); 357 } 358 359 refEx.setNameResolved(true); 360 361 // append (referrals from) the exception that generated this 362 // context to the new search results, so that referral processing 363 // can continue 364 ((ReferralEnumeration<Binding>)be).appendUnprocessedReferrals(refEx); 365 366 return (be); 367 368 } catch (LdapReferralException e) { 369 370 // append (referrals from) the exception that generated this 371 // context to the new exception, so that referral processing 372 // can continue 373 374 e.appendUnprocessedReferrals(refEx); 375 throw (NamingException)(e.fillInStackTrace()); 376 377 } catch (NamingException e) { 378 379 // record the exception if there are no remaining referrals 380 if ((refEx != null) && (! refEx.hasMoreReferrals())) { 381 refEx.setNamingException(e); 382 } 383 if ((refEx != null) && 384 (refEx.hasMoreReferrals() || 385 refEx.hasMoreReferralExceptions())) { 386 throw (NamingException) 387 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 388 } else { 389 throw e; 390 } 391 } 392 } 393 destroySubcontext(String name)394 public void destroySubcontext(String name) throws NamingException { 395 destroySubcontext(toName(name)); 396 } 397 destroySubcontext(Name name)398 public void destroySubcontext(Name name) throws NamingException { 399 if (skipThisReferral) { 400 throw (NamingException) 401 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 402 } 403 404 refCtx.destroySubcontext(overrideName(name)); 405 } 406 createSubcontext(String name)407 public Context createSubcontext(String name) throws NamingException { 408 return createSubcontext(toName(name)); 409 } 410 createSubcontext(Name name)411 public Context createSubcontext(Name name) throws NamingException { 412 if (skipThisReferral) { 413 throw (NamingException) 414 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 415 } 416 417 return refCtx.createSubcontext(overrideName(name)); 418 } 419 lookupLink(String name)420 public Object lookupLink(String name) throws NamingException { 421 return lookupLink(toName(name)); 422 } 423 lookupLink(Name name)424 public Object lookupLink(Name name) throws NamingException { 425 if (skipThisReferral) { 426 throw (NamingException) 427 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 428 } 429 430 return refCtx.lookupLink(overrideName(name)); 431 } 432 getNameParser(String name)433 public NameParser getNameParser(String name) throws NamingException { 434 return getNameParser(toName(name)); 435 } 436 getNameParser(Name name)437 public NameParser getNameParser(Name name) throws NamingException { 438 if (skipThisReferral) { 439 throw (NamingException) 440 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 441 } 442 443 return refCtx.getNameParser(overrideName(name)); 444 } 445 composeName(String name, String prefix)446 public String composeName(String name, String prefix) 447 throws NamingException { 448 return composeName(toName(name), toName(prefix)).toString(); 449 } 450 composeName(Name name, Name prefix)451 public Name composeName(Name name, Name prefix) throws NamingException { 452 if (skipThisReferral) { 453 throw (NamingException) 454 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 455 } 456 return refCtx.composeName(name, prefix); 457 } 458 addToEnvironment(String propName, Object propVal)459 public Object addToEnvironment(String propName, Object propVal) 460 throws NamingException { 461 if (skipThisReferral) { 462 throw (NamingException) 463 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 464 } 465 466 return refCtx.addToEnvironment(propName, propVal); 467 } 468 removeFromEnvironment(String propName)469 public Object removeFromEnvironment(String propName) 470 throws NamingException { 471 if (skipThisReferral) { 472 throw (NamingException) 473 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 474 } 475 476 return refCtx.removeFromEnvironment(propName); 477 } 478 getEnvironment()479 public Hashtable<?,?> getEnvironment() throws NamingException { 480 if (skipThisReferral) { 481 throw (NamingException) 482 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 483 } 484 485 return refCtx.getEnvironment(); 486 } 487 getAttributes(String name)488 public Attributes getAttributes(String name) throws NamingException { 489 return getAttributes(toName(name)); 490 } 491 getAttributes(Name name)492 public Attributes getAttributes(Name name) throws NamingException { 493 if (skipThisReferral) { 494 throw (NamingException) 495 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 496 } 497 498 return refCtx.getAttributes(overrideName(name)); 499 } 500 getAttributes(String name, String[] attrIds)501 public Attributes getAttributes(String name, String[] attrIds) 502 throws NamingException { 503 return getAttributes(toName(name), attrIds); 504 } 505 getAttributes(Name name, String[] attrIds)506 public Attributes getAttributes(Name name, String[] attrIds) 507 throws NamingException { 508 if (skipThisReferral) { 509 throw (NamingException) 510 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 511 } 512 513 return refCtx.getAttributes(overrideName(name), attrIds); 514 } 515 modifyAttributes(String name, int mod_op, Attributes attrs)516 public void modifyAttributes(String name, int mod_op, Attributes attrs) 517 throws NamingException { 518 modifyAttributes(toName(name), mod_op, attrs); 519 } 520 modifyAttributes(Name name, int mod_op, Attributes attrs)521 public void modifyAttributes(Name name, int mod_op, Attributes attrs) 522 throws NamingException { 523 if (skipThisReferral) { 524 throw (NamingException) 525 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 526 } 527 528 refCtx.modifyAttributes(overrideName(name), mod_op, attrs); 529 } 530 modifyAttributes(String name, ModificationItem[] mods)531 public void modifyAttributes(String name, ModificationItem[] mods) 532 throws NamingException { 533 modifyAttributes(toName(name), mods); 534 } 535 modifyAttributes(Name name, ModificationItem[] mods)536 public void modifyAttributes(Name name, ModificationItem[] mods) 537 throws NamingException { 538 if (skipThisReferral) { 539 throw (NamingException) 540 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 541 } 542 543 refCtx.modifyAttributes(overrideName(name), mods); 544 } 545 bind(String name, Object obj, Attributes attrs)546 public void bind(String name, Object obj, Attributes attrs) 547 throws NamingException { 548 bind(toName(name), obj, attrs); 549 } 550 bind(Name name, Object obj, Attributes attrs)551 public void bind(Name name, Object obj, Attributes attrs) 552 throws NamingException { 553 if (skipThisReferral) { 554 throw (NamingException) 555 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 556 } 557 558 refCtx.bind(overrideName(name), obj, attrs); 559 } 560 rebind(String name, Object obj, Attributes attrs)561 public void rebind(String name, Object obj, Attributes attrs) 562 throws NamingException { 563 rebind(toName(name), obj, attrs); 564 } 565 rebind(Name name, Object obj, Attributes attrs)566 public void rebind(Name name, Object obj, Attributes attrs) 567 throws NamingException { 568 if (skipThisReferral) { 569 throw (NamingException) 570 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 571 } 572 573 refCtx.rebind(overrideName(name), obj, attrs); 574 } 575 createSubcontext(String name, Attributes attrs)576 public DirContext createSubcontext(String name, Attributes attrs) 577 throws NamingException { 578 return createSubcontext(toName(name), attrs); 579 } 580 createSubcontext(Name name, Attributes attrs)581 public DirContext createSubcontext(Name name, Attributes attrs) 582 throws NamingException { 583 if (skipThisReferral) { 584 throw (NamingException) 585 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 586 } 587 588 return refCtx.createSubcontext(overrideName(name), attrs); 589 } 590 getSchema(String name)591 public DirContext getSchema(String name) throws NamingException { 592 return getSchema(toName(name)); 593 } 594 getSchema(Name name)595 public DirContext getSchema(Name name) throws NamingException { 596 if (skipThisReferral) { 597 throw (NamingException) 598 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 599 } 600 601 return refCtx.getSchema(overrideName(name)); 602 } 603 getSchemaClassDefinition(String name)604 public DirContext getSchemaClassDefinition(String name) 605 throws NamingException { 606 return getSchemaClassDefinition(toName(name)); 607 } 608 getSchemaClassDefinition(Name name)609 public DirContext getSchemaClassDefinition(Name name) 610 throws NamingException { 611 if (skipThisReferral) { 612 throw (NamingException) 613 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 614 } 615 616 return refCtx.getSchemaClassDefinition(overrideName(name)); 617 } 618 search(String name, Attributes matchingAttributes)619 public NamingEnumeration<SearchResult> search(String name, 620 Attributes matchingAttributes) 621 throws NamingException { 622 return search(toName(name), SearchFilter.format(matchingAttributes), 623 new SearchControls()); 624 } 625 search(Name name, Attributes matchingAttributes)626 public NamingEnumeration<SearchResult> search(Name name, 627 Attributes matchingAttributes) 628 throws NamingException { 629 return search(name, SearchFilter.format(matchingAttributes), 630 new SearchControls()); 631 } 632 search(String name, Attributes matchingAttributes, String[] attributesToReturn)633 public NamingEnumeration<SearchResult> search(String name, 634 Attributes matchingAttributes, 635 String[] attributesToReturn) 636 throws NamingException { 637 SearchControls cons = new SearchControls(); 638 cons.setReturningAttributes(attributesToReturn); 639 640 return search(toName(name), SearchFilter.format(matchingAttributes), 641 cons); 642 } 643 search(Name name, Attributes matchingAttributes, String[] attributesToReturn)644 public NamingEnumeration<SearchResult> search(Name name, 645 Attributes matchingAttributes, 646 String[] attributesToReturn) 647 throws NamingException { 648 SearchControls cons = new SearchControls(); 649 cons.setReturningAttributes(attributesToReturn); 650 651 return search(name, SearchFilter.format(matchingAttributes), cons); 652 } 653 search(String name, String filter, SearchControls cons)654 public NamingEnumeration<SearchResult> search(String name, 655 String filter, 656 SearchControls cons) 657 throws NamingException { 658 return search(toName(name), filter, cons); 659 } 660 search(Name name, String filter, SearchControls cons)661 public NamingEnumeration<SearchResult> search(Name name, 662 String filter, 663 SearchControls cons) throws NamingException { 664 665 if (skipThisReferral) { 666 throw (NamingException) 667 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 668 } 669 670 try { 671 NamingEnumeration<SearchResult> se = 672 refCtx.search(overrideName(name), 673 overrideFilter(filter), 674 overrideAttributesAndScope(cons)); 675 676 refEx.setNameResolved(true); 677 678 // append (referrals from) the exception that generated this 679 // context to the new search results, so that referral processing 680 // can continue 681 ((ReferralEnumeration)se).appendUnprocessedReferrals(refEx); 682 683 return (se); 684 685 } catch (LdapReferralException e) { 686 687 // %%% setNameResolved(true); 688 689 // append (referrals from) the exception that generated this 690 // context to the new exception, so that referral processing 691 // can continue 692 693 e.appendUnprocessedReferrals(refEx); 694 throw (NamingException)(e.fillInStackTrace()); 695 696 } catch (NamingException e) { 697 698 // record the exception if there are no remaining referrals 699 if ((refEx != null) && (! refEx.hasMoreReferrals())) { 700 refEx.setNamingException(e); 701 } 702 if ((refEx != null) && 703 (refEx.hasMoreReferrals() || 704 refEx.hasMoreReferralExceptions())) { 705 throw (NamingException) 706 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 707 } else { 708 throw e; 709 } 710 } 711 } 712 search(String name, String filterExpr, Object[] filterArgs, SearchControls cons)713 public NamingEnumeration<SearchResult> search(String name, 714 String filterExpr, 715 Object[] filterArgs, 716 SearchControls cons) 717 throws NamingException { 718 return search(toName(name), filterExpr, filterArgs, cons); 719 } 720 search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons)721 public NamingEnumeration<SearchResult> search(Name name, 722 String filterExpr, 723 Object[] filterArgs, 724 SearchControls cons) throws NamingException { 725 726 if (skipThisReferral) { 727 throw (NamingException) 728 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 729 } 730 731 try { 732 NamingEnumeration<SearchResult> se; 733 734 if (urlFilter != null) { 735 se = refCtx.search(overrideName(name), urlFilter, 736 overrideAttributesAndScope(cons)); 737 } else { 738 se = refCtx.search(overrideName(name), filterExpr, 739 filterArgs, overrideAttributesAndScope(cons)); 740 } 741 742 refEx.setNameResolved(true); 743 744 // append (referrals from) the exception that generated this 745 // context to the new search results, so that referral processing 746 // can continue 747 ((ReferralEnumeration)se).appendUnprocessedReferrals(refEx); 748 749 return (se); 750 751 } catch (LdapReferralException e) { 752 753 // append (referrals from) the exception that generated this 754 // context to the new exception, so that referral processing 755 // can continue 756 757 e.appendUnprocessedReferrals(refEx); 758 throw (NamingException)(e.fillInStackTrace()); 759 760 } catch (NamingException e) { 761 762 // record the exception if there are no remaining referrals 763 if ((refEx != null) && (! refEx.hasMoreReferrals())) { 764 refEx.setNamingException(e); 765 } 766 if ((refEx != null) && 767 (refEx.hasMoreReferrals() || 768 refEx.hasMoreReferralExceptions())) { 769 throw (NamingException) 770 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 771 } else { 772 throw e; 773 } 774 } 775 } 776 getNameInNamespace()777 public String getNameInNamespace() throws NamingException { 778 if (skipThisReferral) { 779 throw (NamingException) 780 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 781 } 782 return urlName != null && !urlName.isEmpty() ? urlName.get(0) : ""; 783 } 784 785 // ---------------------- LdapContext --------------------- 786 extendedOperation(ExtendedRequest request)787 public ExtendedResponse extendedOperation(ExtendedRequest request) 788 throws NamingException { 789 790 if (skipThisReferral) { 791 throw (NamingException) 792 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 793 } 794 795 if (!(refCtx instanceof LdapContext)) { 796 throw new NotContextException( 797 "Referral context not an instance of LdapContext"); 798 } 799 800 return ((LdapContext)refCtx).extendedOperation(request); 801 } 802 newInstance(Control[] requestControls)803 public LdapContext newInstance(Control[] requestControls) 804 throws NamingException { 805 806 if (skipThisReferral) { 807 throw (NamingException) 808 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 809 } 810 811 if (!(refCtx instanceof LdapContext)) { 812 throw new NotContextException( 813 "Referral context not an instance of LdapContext"); 814 } 815 816 return ((LdapContext)refCtx).newInstance(requestControls); 817 } 818 reconnect(Control[] connCtls)819 public void reconnect(Control[] connCtls) throws NamingException { 820 if (skipThisReferral) { 821 throw (NamingException) 822 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 823 } 824 825 if (!(refCtx instanceof LdapContext)) { 826 throw new NotContextException( 827 "Referral context not an instance of LdapContext"); 828 } 829 830 ((LdapContext)refCtx).reconnect(connCtls); 831 } 832 getConnectControls()833 public Control[] getConnectControls() throws NamingException { 834 if (skipThisReferral) { 835 throw (NamingException) 836 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 837 } 838 839 if (!(refCtx instanceof LdapContext)) { 840 throw new NotContextException( 841 "Referral context not an instance of LdapContext"); 842 } 843 844 return ((LdapContext)refCtx).getConnectControls(); 845 } 846 setRequestControls(Control[] requestControls)847 public void setRequestControls(Control[] requestControls) 848 throws NamingException { 849 850 if (skipThisReferral) { 851 throw (NamingException) 852 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 853 } 854 855 if (!(refCtx instanceof LdapContext)) { 856 throw new NotContextException( 857 "Referral context not an instance of LdapContext"); 858 } 859 860 ((LdapContext)refCtx).setRequestControls(requestControls); 861 } 862 getRequestControls()863 public Control[] getRequestControls() throws NamingException { 864 if (skipThisReferral) { 865 throw (NamingException) 866 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 867 } 868 869 if (!(refCtx instanceof LdapContext)) { 870 throw new NotContextException( 871 "Referral context not an instance of LdapContext"); 872 } 873 return ((LdapContext)refCtx).getRequestControls(); 874 } 875 getResponseControls()876 public Control[] getResponseControls() throws NamingException { 877 if (skipThisReferral) { 878 throw (NamingException) 879 ((refEx.appendUnprocessedReferrals(null)).fillInStackTrace()); 880 } 881 882 if (!(refCtx instanceof LdapContext)) { 883 throw new NotContextException( 884 "Referral context not an instance of LdapContext"); 885 } 886 return ((LdapContext)refCtx).getResponseControls(); 887 } 888 889 // ---------------------- Private methods --------------------- toName(String name)890 private Name toName(String name) throws InvalidNameException { 891 return name.isEmpty() ? new CompositeName() : 892 new CompositeName().add(name); 893 } 894 895 /* 896 * Use the DN component from the LDAP URL (if present) to override the 897 * supplied DN. 898 */ overrideName(Name name)899 private Name overrideName(Name name) throws InvalidNameException { 900 return (urlName == null ? name : urlName); 901 } 902 903 /* 904 * Use the attributes and scope components from the LDAP URL (if present) 905 * to override the corresponding components supplied in SearchControls. 906 */ overrideAttributesAndScope(SearchControls cons)907 private SearchControls overrideAttributesAndScope(SearchControls cons) { 908 SearchControls urlCons; 909 910 if ((urlScope != null) || (urlAttrs != null)) { 911 urlCons = new SearchControls(cons.getSearchScope(), 912 cons.getCountLimit(), 913 cons.getTimeLimit(), 914 cons.getReturningAttributes(), 915 cons.getReturningObjFlag(), 916 cons.getDerefLinkFlag()); 917 918 if (urlScope != null) { 919 if (urlScope.equals("base")) { 920 urlCons.setSearchScope(SearchControls.OBJECT_SCOPE); 921 } else if (urlScope.equals("one")) { 922 urlCons.setSearchScope(SearchControls.ONELEVEL_SCOPE); 923 } else if (urlScope.equals("sub")) { 924 urlCons.setSearchScope(SearchControls.SUBTREE_SCOPE); 925 } 926 } 927 928 if (urlAttrs != null) { 929 StringTokenizer tokens = new StringTokenizer(urlAttrs, ","); 930 int count = tokens.countTokens(); 931 String[] attrs = new String[count]; 932 for (int i = 0; i < count; i ++) { 933 attrs[i] = tokens.nextToken(); 934 } 935 urlCons.setReturningAttributes(attrs); 936 } 937 938 return urlCons; 939 940 } else { 941 return cons; 942 } 943 } 944 945 /* 946 * Use the filter component from the LDAP URL (if present) to override the 947 * supplied filter. 948 */ overrideFilter(String filter)949 private String overrideFilter(String filter) { 950 return (urlFilter == null ? filter : urlFilter); 951 } 952 953 } 954