1 /* 2 * Copyright (c) 1999, 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.url.ldap; 27 28 import javax.naming.spi.ResolveResult; 29 import javax.naming.*; 30 import javax.naming.directory.*; 31 import java.util.Hashtable; 32 import java.util.StringTokenizer; 33 import com.sun.jndi.ldap.LdapURL; 34 35 /** 36 * An LDAP URL context. 37 * 38 * @author Rosanna Lee 39 * @author Scott Seligman 40 */ 41 42 final public class ldapURLContext 43 extends com.sun.jndi.toolkit.url.GenericURLDirContext { 44 45 ldapURLContext(Hashtable env) { 46 super(env); 47 } 48 49 /** 50 * Resolves 'name' into a target context with remaining name. 51 * It only resolves the hostname/port number. The remaining name 52 * contains the root DN. 53 * 54 * For example, with a LDAP URL "ldap://localhost:389/o=widget,c=us", 55 * this method resolves "ldap://localhost:389/" to the root LDAP 56 * context on the server 'localhost' on port 389, 57 * and returns as the remaining name "o=widget, c=us". 58 */ 59 protected ResolveResult getRootURLContext(String name, Hashtable env) 60 throws NamingException { 61 return ldapURLContextFactory.getUsingURLIgnoreRootDN(name, env); 62 } 63 64 /** 65 * Return the suffix of an ldap url. 66 * prefix parameter is ignored. 67 */ 68 protected Name getURLSuffix(String prefix, String url) 69 throws NamingException { 70 71 LdapURL ldapUrl = new LdapURL(url); 72 String dn = (ldapUrl.getDN() != null? ldapUrl.getDN() : ""); 73 74 // Represent DN as empty or single-component composite name. 75 CompositeName remaining = new CompositeName(); 76 if (!"".equals(dn)) { 77 // if nonempty, add component 78 remaining.add(dn); 79 } 80 return remaining; 81 } 82 83 /* 84 * Override context operations. 85 * Test for presence of LDAP URL query components in the name argument. 86 * Query components are permitted only for search operations and only 87 * when the name has a single component. 88 */ 89 90 public Object lookup(String name) throws NamingException { 91 if (LdapURL.hasQueryComponents(name)) { 92 throw new InvalidNameException(name); 93 } else { 94 return super.lookup(name); 95 } 96 } 97 98 public Object lookup(Name name) throws NamingException { 99 if (LdapURL.hasQueryComponents(name.get(0))) { 100 throw new InvalidNameException(name.toString()); 101 } else { 102 return super.lookup(name); 103 } 104 } 105 106 public void bind(String name, Object obj) throws NamingException { 107 if (LdapURL.hasQueryComponents(name)) { 108 throw new InvalidNameException(name); 109 } else { 110 super.bind(name, obj); 111 } 112 } 113 114 public void bind(Name name, Object obj) throws NamingException { 115 if (LdapURL.hasQueryComponents(name.get(0))) { 116 throw new InvalidNameException(name.toString()); 117 } else { 118 super.bind(name, obj); 119 } 120 } 121 122 public void rebind(String name, Object obj) throws NamingException { 123 if (LdapURL.hasQueryComponents(name)) { 124 throw new InvalidNameException(name); 125 } else { 126 super.rebind(name, obj); 127 } 128 } 129 130 public void rebind(Name name, Object obj) throws NamingException { 131 if (LdapURL.hasQueryComponents(name.get(0))) { 132 throw new InvalidNameException(name.toString()); 133 } else { 134 super.rebind(name, obj); 135 } 136 } 137 138 public void unbind(String name) throws NamingException { 139 if (LdapURL.hasQueryComponents(name)) { 140 throw new InvalidNameException(name); 141 } else { 142 super.unbind(name); 143 } 144 } 145 146 public void unbind(Name name) throws NamingException { 147 if (LdapURL.hasQueryComponents(name.get(0))) { 148 throw new InvalidNameException(name.toString()); 149 } else { 150 super.unbind(name); 151 } 152 } 153 154 public void rename(String oldName, String newName) throws NamingException { 155 if (LdapURL.hasQueryComponents(oldName)) { 156 throw new InvalidNameException(oldName); 157 } else if (LdapURL.hasQueryComponents(newName)) { 158 throw new InvalidNameException(newName); 159 } else { 160 super.rename(oldName, newName); 161 } 162 } 163 164 public void rename(Name oldName, Name newName) throws NamingException { 165 if (LdapURL.hasQueryComponents(oldName.get(0))) { 166 throw new InvalidNameException(oldName.toString()); 167 } else if (LdapURL.hasQueryComponents(newName.get(0))) { 168 throw new InvalidNameException(newName.toString()); 169 } else { 170 super.rename(oldName, newName); 171 } 172 } 173 174 public NamingEnumeration list(String name) throws NamingException { 175 if (LdapURL.hasQueryComponents(name)) { 176 throw new InvalidNameException(name); 177 } else { 178 return super.list(name); 179 } 180 } 181 182 public NamingEnumeration list(Name name) throws NamingException { 183 if (LdapURL.hasQueryComponents(name.get(0))) { 184 throw new InvalidNameException(name.toString()); 185 } else { 186 return super.list(name); 187 } 188 } 189 190 public NamingEnumeration listBindings(String name) throws NamingException { 191 if (LdapURL.hasQueryComponents(name)) { 192 throw new InvalidNameException(name); 193 } else { 194 return super.listBindings(name); 195 } 196 } 197 198 public NamingEnumeration listBindings(Name name) throws NamingException { 199 if (LdapURL.hasQueryComponents(name.get(0))) { 200 throw new InvalidNameException(name.toString()); 201 } else { 202 return super.listBindings(name); 203 } 204 } 205 206 public void destroySubcontext(String name) throws NamingException { 207 if (LdapURL.hasQueryComponents(name)) { 208 throw new InvalidNameException(name); 209 } else { 210 super.destroySubcontext(name); 211 } 212 } 213 214 public void destroySubcontext(Name name) throws NamingException { 215 if (LdapURL.hasQueryComponents(name.get(0))) { 216 throw new InvalidNameException(name.toString()); 217 } else { 218 super.destroySubcontext(name); 219 } 220 } 221 222 public Context createSubcontext(String name) throws NamingException { 223 if (LdapURL.hasQueryComponents(name)) { 224 throw new InvalidNameException(name); 225 } else { 226 return super.createSubcontext(name); 227 } 228 } 229 230 public Context createSubcontext(Name name) throws NamingException { 231 if (LdapURL.hasQueryComponents(name.get(0))) { 232 throw new InvalidNameException(name.toString()); 233 } else { 234 return super.createSubcontext(name); 235 } 236 } 237 238 public Object lookupLink(String name) throws NamingException { 239 if (LdapURL.hasQueryComponents(name)) { 240 throw new InvalidNameException(name); 241 } else { 242 return super.lookupLink(name); 243 } 244 } 245 246 public Object lookupLink(Name name) throws NamingException { 247 if (LdapURL.hasQueryComponents(name.get(0))) { 248 throw new InvalidNameException(name.toString()); 249 } else { 250 return super.lookupLink(name); 251 } 252 } 253 254 public NameParser getNameParser(String name) throws NamingException { 255 if (LdapURL.hasQueryComponents(name)) { 256 throw new InvalidNameException(name); 257 } else { 258 return super.getNameParser(name); 259 } 260 } 261 262 public NameParser getNameParser(Name name) throws NamingException { 263 if (LdapURL.hasQueryComponents(name.get(0))) { 264 throw new InvalidNameException(name.toString()); 265 } else { 266 return super.getNameParser(name); 267 } 268 } 269 270 public String composeName(String name, String prefix) 271 throws NamingException { 272 if (LdapURL.hasQueryComponents(name)) { 273 throw new InvalidNameException(name); 274 } else if (LdapURL.hasQueryComponents(prefix)) { 275 throw new InvalidNameException(prefix); 276 } else { 277 return super.composeName(name, prefix); 278 } 279 } 280 281 public Name composeName(Name name, Name prefix) throws NamingException { 282 if (LdapURL.hasQueryComponents(name.get(0))) { 283 throw new InvalidNameException(name.toString()); 284 } else if (LdapURL.hasQueryComponents(prefix.get(0))) { 285 throw new InvalidNameException(prefix.toString()); 286 } else { 287 return super.composeName(name, prefix); 288 } 289 } 290 291 public Attributes getAttributes(String name) throws NamingException { 292 if (LdapURL.hasQueryComponents(name)) { 293 throw new InvalidNameException(name); 294 } else { 295 return super.getAttributes(name); 296 } 297 } 298 299 public Attributes getAttributes(Name name) throws NamingException { 300 if (LdapURL.hasQueryComponents(name.get(0))) { 301 throw new InvalidNameException(name.toString()); 302 } else { 303 return super.getAttributes(name); 304 } 305 } 306 307 public Attributes getAttributes(String name, String[] attrIds) 308 throws NamingException { 309 if (LdapURL.hasQueryComponents(name)) { 310 throw new InvalidNameException(name); 311 } else { 312 return super.getAttributes(name, attrIds); 313 } 314 } 315 316 public Attributes getAttributes(Name name, String[] attrIds) 317 throws NamingException { 318 if (LdapURL.hasQueryComponents(name.get(0))) { 319 throw new InvalidNameException(name.toString()); 320 } else { 321 return super.getAttributes(name, attrIds); 322 } 323 } 324 325 public void modifyAttributes(String name, int mod_op, Attributes attrs) 326 throws NamingException { 327 if (LdapURL.hasQueryComponents(name)) { 328 throw new InvalidNameException(name); 329 } else { 330 super.modifyAttributes(name, mod_op, attrs); 331 } 332 } 333 334 public void modifyAttributes(Name name, int mod_op, Attributes attrs) 335 throws NamingException { 336 if (LdapURL.hasQueryComponents(name.get(0))) { 337 throw new InvalidNameException(name.toString()); 338 } else { 339 super.modifyAttributes(name, mod_op, attrs); 340 } 341 } 342 343 public void modifyAttributes(String name, ModificationItem[] mods) 344 throws NamingException { 345 if (LdapURL.hasQueryComponents(name)) { 346 throw new InvalidNameException(name); 347 } else { 348 super.modifyAttributes(name, mods); 349 } 350 } 351 352 public void modifyAttributes(Name name, ModificationItem[] mods) 353 throws NamingException { 354 if (LdapURL.hasQueryComponents(name.get(0))) { 355 throw new InvalidNameException(name.toString()); 356 } else { 357 super.modifyAttributes(name, mods); 358 } 359 } 360 361 public void bind(String name, Object obj, Attributes attrs) 362 throws NamingException { 363 if (LdapURL.hasQueryComponents(name)) { 364 throw new InvalidNameException(name); 365 } else { 366 super.bind(name, obj, attrs); 367 } 368 } 369 370 public void bind(Name name, Object obj, Attributes attrs) 371 throws NamingException { 372 if (LdapURL.hasQueryComponents(name.get(0))) { 373 throw new InvalidNameException(name.toString()); 374 } else { 375 super.bind(name, obj, attrs); 376 } 377 } 378 379 public void rebind(String name, Object obj, Attributes attrs) 380 throws NamingException { 381 if (LdapURL.hasQueryComponents(name)) { 382 throw new InvalidNameException(name); 383 } else { 384 super.rebind(name, obj, attrs); 385 } 386 } 387 388 public void rebind(Name name, Object obj, Attributes attrs) 389 throws NamingException { 390 if (LdapURL.hasQueryComponents(name.get(0))) { 391 throw new InvalidNameException(name.toString()); 392 } else { 393 super.rebind(name, obj, attrs); 394 } 395 } 396 397 public DirContext createSubcontext(String name, Attributes attrs) 398 throws NamingException { 399 if (LdapURL.hasQueryComponents(name)) { 400 throw new InvalidNameException(name); 401 } else { 402 return super.createSubcontext(name, attrs); 403 } 404 } 405 406 public DirContext createSubcontext(Name name, Attributes attrs) 407 throws NamingException { 408 if (LdapURL.hasQueryComponents(name.get(0))) { 409 throw new InvalidNameException(name.toString()); 410 } else { 411 return super.createSubcontext(name, attrs); 412 } 413 } 414 415 public DirContext getSchema(String name) throws NamingException { 416 if (LdapURL.hasQueryComponents(name)) { 417 throw new InvalidNameException(name); 418 } else { 419 return super.getSchema(name); 420 } 421 } 422 423 public DirContext getSchema(Name name) throws NamingException { 424 if (LdapURL.hasQueryComponents(name.get(0))) { 425 throw new InvalidNameException(name.toString()); 426 } else { 427 return super.getSchema(name); 428 } 429 } 430 431 public DirContext getSchemaClassDefinition(String name) 432 throws NamingException { 433 if (LdapURL.hasQueryComponents(name)) { 434 throw new InvalidNameException(name); 435 } else { 436 return super.getSchemaClassDefinition(name); 437 } 438 } 439 440 public DirContext getSchemaClassDefinition(Name name) 441 throws NamingException { 442 if (LdapURL.hasQueryComponents(name.get(0))) { 443 throw new InvalidNameException(name.toString()); 444 } else { 445 return super.getSchemaClassDefinition(name); 446 } 447 } 448 449 // divert the search operation when the LDAP URL has query components 450 public NamingEnumeration search(String name, 451 Attributes matchingAttributes) 452 throws NamingException { 453 454 if (LdapURL.hasQueryComponents(name)) { 455 return searchUsingURL(name); 456 } else { 457 return super.search(name, matchingAttributes); 458 } 459 } 460 461 // divert the search operation when name has a single component 462 public NamingEnumeration search(Name name, 463 Attributes matchingAttributes) 464 throws NamingException { 465 if (name.size() == 1) { 466 return search(name.get(0), matchingAttributes); 467 } else if (LdapURL.hasQueryComponents(name.get(0))) { 468 throw new InvalidNameException(name.toString()); 469 } else { 470 return super.search(name, matchingAttributes); 471 } 472 } 473 474 // divert the search operation when the LDAP URL has query components 475 public NamingEnumeration search(String name, 476 Attributes matchingAttributes, 477 String[] attributesToReturn) 478 throws NamingException { 479 480 if (LdapURL.hasQueryComponents(name)) { 481 return searchUsingURL(name); 482 } else { 483 return super.search(name, matchingAttributes, attributesToReturn); 484 } 485 } 486 487 // divert the search operation when name has a single component 488 public NamingEnumeration search(Name name, 489 Attributes matchingAttributes, 490 String[] attributesToReturn) 491 throws NamingException { 492 493 if (name.size() == 1) { 494 return search(name.get(0), matchingAttributes, attributesToReturn); 495 } else if (LdapURL.hasQueryComponents(name.get(0))) { 496 throw new InvalidNameException(name.toString()); 497 } else { 498 return super.search(name, matchingAttributes, attributesToReturn); 499 } 500 } 501 502 // divert the search operation when the LDAP URL has query components 503 public NamingEnumeration search(String name, 504 String filter, 505 SearchControls cons) 506 throws NamingException { 507 508 if (LdapURL.hasQueryComponents(name)) { 509 return searchUsingURL(name); 510 } else { 511 return super.search(name, filter, cons); 512 } 513 } 514 515 // divert the search operation when name has a single component 516 public NamingEnumeration search(Name name, 517 String filter, 518 SearchControls cons) 519 throws NamingException { 520 521 if (name.size() == 1) { 522 return search(name.get(0), filter, cons); 523 } else if (LdapURL.hasQueryComponents(name.get(0))) { 524 throw new InvalidNameException(name.toString()); 525 } else { 526 return super.search(name, filter, cons); 527 } 528 } 529 530 // divert the search operation when the LDAP URL has query components 531 public NamingEnumeration search(String name, 532 String filterExpr, 533 Object[] filterArgs, 534 SearchControls cons) 535 throws NamingException { 536 537 if (LdapURL.hasQueryComponents(name)) { 538 return searchUsingURL(name); 539 } else { 540 return super.search(name, filterExpr, filterArgs, cons); 541 } 542 } 543 544 // divert the search operation when name has a single component 545 public NamingEnumeration search(Name name, 546 String filterExpr, 547 Object[] filterArgs, 548 SearchControls cons) 549 throws NamingException { 550 551 if (name.size() == 1) { 552 return search(name.get(0), filterExpr, filterArgs, cons); 553 } else if (LdapURL.hasQueryComponents(name.get(0))) { 554 throw new InvalidNameException(name.toString()); 555 } else { 556 return super.search(name, filterExpr, filterArgs, cons); 557 } 558 } 559 560 // Search using the LDAP URL in name. 561 // LDAP URL query components override the search argments. 562 private NamingEnumeration searchUsingURL(String name) 563 throws NamingException { 564 565 LdapURL url = new LdapURL(name); 566 567 ResolveResult res = getRootURLContext(name, myEnv); 568 DirContext ctx = (DirContext)res.getResolvedObj(); 569 try { 570 return ctx.search(res.getRemainingName(), 571 setFilterUsingURL(url), 572 setSearchControlsUsingURL(url)); 573 } finally { 574 ctx.close(); 575 } 576 } 577 578 /* 579 * Initialize a String filter using the LDAP URL filter component. 580 * If filter is not present in the URL it is initialized to its default 581 * value as specified in RFC-2255. 582 */ 583 private static String setFilterUsingURL(LdapURL url) { 584 585 String filter = url.getFilter(); 586 587 if (filter == null) { 588 filter = "(objectClass=*)"; //default value 589 } 590 return filter; 591 } 592 593 /* 594 * Initialize a SearchControls object using LDAP URL query components. 595 * Components not present in the URL are initialized to their default 596 * values as specified in RFC-2255. 597 */ 598 private static SearchControls setSearchControlsUsingURL(LdapURL url) { 599 600 SearchControls cons = new SearchControls(); 601 String scope = url.getScope(); 602 String attributes = url.getAttributes(); 603 604 if (scope == null) { 605 cons.setSearchScope(SearchControls.OBJECT_SCOPE); //default value 606 } else { 607 if (scope.equals("sub")) { 608 cons.setSearchScope(SearchControls.SUBTREE_SCOPE); 609 } else if (scope.equals("one")) { 610 cons.setSearchScope(SearchControls.ONELEVEL_SCOPE); 611 } else if (scope.equals("base")) { 612 cons.setSearchScope(SearchControls.OBJECT_SCOPE); 613 } 614 } 615 616 if (attributes == null) { 617 cons.setReturningAttributes(null); //default value 618 } else { 619 StringTokenizer tokens = new StringTokenizer(attributes, ","); 620 int count = tokens.countTokens(); 621 String[] attrs = new String[count]; 622 for (int i = 0; i < count; i ++) { 623 attrs[i] = tokens.nextToken(); 624 } 625 cons.setReturningAttributes(attrs); 626 } 627 return cons; 628 } 629 }