001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.types; 028 029 030 031 import java.util.Collection; 032 import java.util.HashSet; 033 import java.util.Iterator; 034 import java.util.Set; 035 036 import static org.opends.server.util.Validator.*; 037 038 039 040 /** 041 * This class defines a data structure that may be used to store 042 * information about an authenticated user. Note that structures in 043 * this class allow for multiple authentication types for the same 044 * user, which is not currently supported by LDAP but may be offered 045 * through some type of extension. 046 */ 047 @org.opends.server.types.PublicAPI( 048 stability=org.opends.server.types.StabilityLevel.UNCOMMITTED, 049 mayInstantiate=true, 050 mayExtend=false, 051 mayInvoke=true) 052 public final class AuthenticationInfo 053 { 054 // The password used to authenticate using simple authentication. 055 private ByteString simplePassword; 056 057 // Indicates whether this connection is currently authenticated. 058 private boolean isAuthenticated; 059 060 // Indicates whether this connection is authenticated as a root 061 // user. 062 private boolean isRoot; 063 064 // Indicates whether the user's password must be changed before any 065 // other operation will be allowed. 066 private boolean mustChangePassword; 067 068 // The entry of the user that is currently authenticated. 069 private Entry authenticationEntry; 070 071 // The entry of the user that will be used as the default 072 // authorization identity. 073 private Entry authorizationEntry; 074 075 // The type of authentication performed on this connection. 076 private Set<AuthenticationType> authenticationTypes; 077 078 // The SASL mechanism used to authenticate. 079 private Set<String> saslMechanisms; 080 081 082 083 /** 084 * Creates a new set of authentication information to be used for 085 * unauthenticated clients. 086 */ 087 public AuthenticationInfo() 088 { 089 isAuthenticated = false; 090 isRoot = false; 091 mustChangePassword = false; 092 simplePassword = null; 093 authenticationTypes = new HashSet<AuthenticationType>(0); 094 authenticationEntry = null; 095 authorizationEntry = null; 096 saslMechanisms = new HashSet<String>(0); 097 } 098 099 100 101 /** 102 * Creates a new set of authentication information to be used for 103 * clients that are authenticated internally. 104 * 105 * @param authenticationEntry The entry of the user that has 106 * authenticated, or {@code null} to 107 * indicate an unauthenticated user. 108 * @param isRoot Indicates whether the authenticated 109 * user is a root user. 110 */ 111 public AuthenticationInfo(Entry authenticationEntry, boolean isRoot) 112 { 113 this.authenticationEntry = authenticationEntry; 114 this.isRoot = isRoot; 115 116 isAuthenticated = (authenticationEntry != null); 117 mustChangePassword = false; 118 simplePassword = null; 119 authorizationEntry = authenticationEntry; 120 saslMechanisms = new HashSet<String>(0); 121 authenticationTypes = new HashSet<AuthenticationType>(1); 122 123 authenticationTypes.add(AuthenticationType.INTERNAL); 124 } 125 126 127 128 /** 129 * Creates a new set of authentication information to be used for 130 * clients that have successfully performed simple authentication. 131 * 132 * @param authenticationEntry The entry of the user that has 133 * authenticated. It must not be 134 * {@code null}. 135 * @param simplePassword The password that was used to 136 * perform the simple authentication. 137 * It must not be {@code null}. 138 * @param isRoot Indicates whether the authenticated 139 * user is a root user. 140 */ 141 public AuthenticationInfo(Entry authenticationEntry, 142 ByteString simplePassword, boolean isRoot) 143 { 144 ensureNotNull(authenticationEntry, simplePassword); 145 146 this.authenticationEntry = authenticationEntry; 147 this.simplePassword = simplePassword; 148 this.isRoot = isRoot; 149 150 isAuthenticated = true; 151 mustChangePassword = false; 152 authorizationEntry = authenticationEntry; 153 saslMechanisms = new HashSet<String>(0); 154 authenticationTypes = new HashSet<AuthenticationType>(1); 155 156 authenticationTypes.add(AuthenticationType.SIMPLE); 157 } 158 159 160 161 /** 162 * Creates a new set of authentication information to be used for 163 * clients that have authenticated using a SASL mechanism. 164 * 165 * @param authenticationEntry The entry of the user that has 166 * authenticated. It must not be 167 * {@code null}. 168 * @param saslMechanism The SASL mechanism used to 169 * authenticate. This must be provided 170 * in all-uppercase characters and must 171 * not be {@code null}. 172 * @param isRoot Indicates whether the authenticated 173 * user is a root user. 174 */ 175 public AuthenticationInfo(Entry authenticationEntry, 176 String saslMechanism, boolean isRoot) 177 { 178 ensureNotNull(authenticationEntry, saslMechanism); 179 180 this.authenticationEntry = authenticationEntry; 181 this.isRoot = isRoot; 182 183 isAuthenticated = true; 184 mustChangePassword = false; 185 authorizationEntry = authenticationEntry; 186 simplePassword = null; 187 188 authenticationTypes = new HashSet<AuthenticationType>(1); 189 authenticationTypes.add(AuthenticationType.SASL); 190 191 saslMechanisms = new HashSet<String>(1); 192 saslMechanisms.add(saslMechanism); 193 } 194 195 196 197 /** 198 * Creates a new set of authentication information to be used for 199 * clients that have authenticated using a SASL mechanism. 200 * 201 * @param authenticationEntry The entry of the user that has 202 * authenticated. It must not be 203 * {@code null}. 204 * @param authorizationEntry The entry of the user that will be 205 * used as the default authorization 206 * identity, or {@code null} to 207 * indicate that the authorization 208 * identity should be the 209 * unauthenticated user. 210 * @param saslMechanism The SASL mechanism used to 211 * authenticate. This must be provided 212 * in all-uppercase characters and must 213 * not be {@code null}. 214 * @param isRoot Indicates whether the authenticated 215 * user is a root user. 216 */ 217 public AuthenticationInfo(Entry authenticationEntry, 218 Entry authorizationEntry, 219 String saslMechanism, boolean isRoot) 220 { 221 ensureNotNull(authenticationEntry, saslMechanism); 222 223 this.authenticationEntry = authenticationEntry; 224 this.authorizationEntry = authorizationEntry; 225 this.isRoot = isRoot; 226 227 isAuthenticated = true; 228 mustChangePassword = false; 229 simplePassword = null; 230 231 authenticationTypes = new HashSet<AuthenticationType>(1); 232 authenticationTypes.add(AuthenticationType.SASL); 233 234 saslMechanisms = new HashSet<String>(1); 235 saslMechanisms.add(saslMechanism); 236 } 237 238 239 240 /** 241 * Indicates whether this client has successfully authenticated to 242 * the server. 243 * 244 * @return {@code true} if this client has successfully 245 * authenticated to the server, or {@code false} if not. 246 */ 247 public boolean isAuthenticated() 248 { 249 return isAuthenticated; 250 } 251 252 253 254 /** 255 * Sets this authentication info structure to reflect that the 256 * client is not authenticated. 257 */ 258 public void setUnauthenticated() 259 { 260 isAuthenticated = false; 261 isRoot = false; 262 mustChangePassword = false; 263 simplePassword = null; 264 authenticationEntry = null; 265 authorizationEntry = null; 266 267 authenticationTypes.clear(); 268 saslMechanisms.clear(); 269 } 270 271 272 273 /** 274 * Indicates whether this client should be considered a root user. 275 * 276 * @return {@code true} if this client should be considered a root 277 * user, or {@code false} if not. 278 */ 279 public boolean isRoot() 280 { 281 return isRoot; 282 } 283 284 285 286 /** 287 * Indicates whether the authenticated user must change his/her 288 * password before any other operation will be allowed. 289 * 290 * @return {@code true} if the user must change his/her password 291 * before any other operation will be allowed, or 292 * {@code false} if not. 293 */ 294 public boolean mustChangePassword() 295 { 296 return mustChangePassword; 297 } 298 299 300 301 /** 302 * Specifies whether the authenticated user must change his/her 303 * password before any other operation will be allowed. 304 * 305 * @param mustChangePassword Specifies whether the authenticated 306 * user must change his/her password 307 * before any other operation will be 308 * allowed. 309 */ 310 public void setMustChangePassword(boolean mustChangePassword) 311 { 312 this.mustChangePassword = mustChangePassword; 313 } 314 315 316 317 /** 318 * Indicates whether this client has authenticated using the 319 * specified authentication type. 320 * 321 * @param authenticationType The authentication type for which to 322 * make the determination. 323 * 324 * @return {@code true} if the client has authenticated using the 325 * specified authentication type, or {@code false} if not. 326 */ 327 public boolean hasAuthenticationType(AuthenticationType 328 authenticationType) 329 { 330 return authenticationTypes.contains(authenticationType); 331 } 332 333 334 335 /** 336 * Indicates whether this client has authenticated using any of the 337 * authentication types in the given collection. 338 * 339 * @param types The collection of authentication types for which 340 * to make the determination. 341 * 342 * @return {@code true} if the client has authenticated using any 343 * of the specified authentication types, or {@code false} 344 * if not. 345 */ 346 public boolean hasAnyAuthenticationType( 347 Collection<AuthenticationType> types) 348 { 349 for (AuthenticationType t : types) 350 { 351 if (authenticationTypes.contains(t)) 352 { 353 return true; 354 } 355 } 356 357 return false; 358 } 359 360 361 362 /** 363 * Retrieves the set of authentication types performed by the 364 * client. 365 * 366 * @return The set of authentication types performed by the client. 367 */ 368 public Set<AuthenticationType> getAuthenticationTypes() 369 { 370 return authenticationTypes; 371 } 372 373 374 375 /** 376 * Adds the provided authentication type to the set of 377 * authentication types completed by the client. This should only 378 * be used in conjunction with multi-factor or step-up 379 * authentication mechanisms. 380 * 381 * @param authenticationType The authentication type to add for 382 * this client. 383 */ 384 public void addAuthenticationType(AuthenticationType 385 authenticationType) 386 { 387 authenticationTypes.add(authenticationType); 388 } 389 390 391 392 /** 393 * Retrieves the entry for the user as whom the client is 394 * authenticated. 395 * 396 * @return The entry for the user as whom the client is 397 * authenticated, or {@code null} if the client is 398 * unauthenticated. 399 */ 400 public Entry getAuthenticationEntry() 401 { 402 return authenticationEntry; 403 } 404 405 406 407 /** 408 * Retrieves the DN of the user as whom the client is authenticated. 409 * 410 * @return The DN of the user as whom the client is authenticated, 411 * or {@code null} if the client is unauthenticated. 412 */ 413 public DN getAuthenticationDN() 414 { 415 if (authenticationEntry == null) 416 { 417 return null; 418 } 419 else 420 { 421 return authenticationEntry.getDN(); 422 } 423 } 424 425 426 427 /** 428 * Retrieves the entry for the user that should be used as the 429 * default authorization identity. 430 * 431 * @return The entry for the user that should be used as the 432 * default authorization identity, or {@code null} if the 433 * authorization identity should be the unauthenticated 434 * user. 435 */ 436 public Entry getAuthorizationEntry() 437 { 438 return authorizationEntry; 439 } 440 441 442 443 /** 444 * Retrieves the DN for the user that should be used as the default 445 * authorization identity. 446 * 447 * @return The DN for the user that should be used as the default 448 * authorization identity, or {@code null} if the 449 * authorization identity should be the unauthenticated 450 * user. 451 */ 452 public DN getAuthorizationDN() 453 { 454 if (authorizationEntry == null) 455 { 456 return null; 457 } 458 else 459 { 460 return authorizationEntry.getDN(); 461 } 462 } 463 464 465 466 /** 467 * Retrieves the password that the client used for simple 468 * authentication. 469 * 470 * @return The password that the client used for simple 471 * authentication, or {@code null} if the client is not 472 * authenticated using simple authentication. 473 */ 474 public ByteString getSimplePassword() 475 { 476 return simplePassword; 477 } 478 479 480 481 /** 482 * Indicates whether the client is currently authenticated using the 483 * specified SASL mechanism. 484 * 485 * @param saslMechanism The SASL mechanism for which to make the 486 * determination. Note that this must be 487 * provided in all uppercase characters. 488 * 489 * @return {@code true} if the client is authenticated using the 490 * specified SASL mechanism, or {@code false} if not. 491 */ 492 public boolean hasSASLMechanism(String saslMechanism) 493 { 494 return saslMechanisms.contains(saslMechanism); 495 } 496 497 498 499 /** 500 * Indicates whether this client has authenticated using any of the 501 * SASL mechanisms in the given collection. 502 * 503 * @param mechanisms The collection of SASL mechanisms for which 504 * to make the determination. 505 * 506 * @return {@code true} if the client has authenticated using any 507 * of the provided SASL mechanisms, or {@code false} if 508 * not. 509 */ 510 public boolean hasAnySASLMechanism(Collection<String> mechanisms) 511 { 512 for (String s : mechanisms) 513 { 514 if (saslMechanisms.contains(s)) 515 { 516 return true; 517 } 518 } 519 520 return false; 521 } 522 523 524 525 /** 526 * Retrieves the set of mechanisms that the client used for SASL 527 * authentication. 528 * 529 * @return The set of mechanisms that the client used for SASL 530 * authentication, or an empty set if SASL mechanism has 531 * not been used. 532 */ 533 public Set<String> getSASLMechanisms() 534 { 535 return saslMechanisms; 536 } 537 538 539 540 /** 541 * Adds the provided mechanism to the set of SASL mechanisms used by 542 * the client. This should only be used in conjunction with 543 * multi-factor or step-up authentication mechanisms. 544 * 545 * @param saslMechanism The SASL mechanism to add to set of 546 * mechanisms for this client. Note that 547 * this must be provided in all uppercase 548 * characters. 549 */ 550 public void addSASLMechanism(String saslMechanism) 551 { 552 saslMechanisms.add(saslMechanism); 553 } 554 555 556 557 /** 558 * Retrieves a string representation of this authentication info 559 * structure. 560 * 561 * @return A string representation of this authentication info 562 * structure. 563 */ 564 public String toString() 565 { 566 StringBuilder buffer = new StringBuilder(); 567 toString(buffer); 568 569 return buffer.toString(); 570 } 571 572 573 574 /** 575 * Appends a string representation of this authentication info 576 * structure to the provided buffer. 577 * 578 * @param buffer The buffer to which the information is to be 579 * appended. 580 */ 581 public void toString(StringBuilder buffer) 582 { 583 buffer.append("AuthenticationInfo(isAuthenticated="); 584 buffer.append(isAuthenticated); 585 buffer.append(",isRoot="); 586 buffer.append(isRoot); 587 buffer.append(",mustChangePassword="); 588 buffer.append(mustChangePassword); 589 buffer.append(",authenticationDN=\""); 590 591 if (authenticationEntry != null) 592 { 593 authenticationEntry.getDN().toString(buffer); 594 } 595 596 if (authorizationEntry == null) 597 { 598 buffer.append("\",authorizationDN=\"\""); 599 } 600 else 601 { 602 buffer.append("\",authorizationDN=\""); 603 authorizationEntry.getDN().toString(buffer); 604 buffer.append("\""); 605 } 606 607 if (! authenticationTypes.isEmpty()) 608 { 609 Iterator<AuthenticationType> iterator = 610 authenticationTypes.iterator(); 611 AuthenticationType authType = iterator.next(); 612 613 if (iterator.hasNext()) 614 { 615 buffer.append(",authTypes={"); 616 buffer.append(authType); 617 618 while (iterator.hasNext()) 619 { 620 buffer.append(","); 621 buffer.append(iterator.next()); 622 } 623 624 buffer.append("}"); 625 } 626 else 627 { 628 buffer.append(",authType="); 629 buffer.append(authType); 630 } 631 } 632 633 if (! saslMechanisms.isEmpty()) 634 { 635 Iterator<String> iterator = saslMechanisms.iterator(); 636 String mech = iterator.next(); 637 638 if (iterator.hasNext()) 639 { 640 buffer.append(",saslMechanisms={"); 641 buffer.append(mech); 642 643 while (iterator.hasNext()) 644 { 645 buffer.append(","); 646 buffer.append(iterator.next()); 647 } 648 649 buffer.append("}"); 650 } 651 else 652 { 653 buffer.append(",saslMechanism="); 654 buffer.append(mech); 655 } 656 } 657 658 buffer.append(")"); 659 } 660 661 662 663 /** 664 * Creates a duplicate of this {@code AuthenticationInfo} object 665 * with the new authentication and authorization entries. 666 * 667 * @param newAuthenticationEntry The updated entry for the user 668 * as whom the associated client 669 * connection is authenticated. 670 * @param newAuthorizationEntry The updated entry for the default 671 * authorization identity for the 672 * associated client connection. 673 * 674 * @return The duplicate of this {@code AuthenticationInfo} object 675 * with the specified authentication and authorization 676 * entries. 677 */ 678 public AuthenticationInfo duplicate(Entry newAuthenticationEntry, 679 Entry newAuthorizationEntry) 680 { 681 AuthenticationInfo authInfo = new AuthenticationInfo(); 682 683 authInfo.simplePassword = simplePassword; 684 authInfo.isAuthenticated = isAuthenticated; 685 authInfo.isRoot = isRoot; 686 authInfo.mustChangePassword = mustChangePassword; 687 authInfo.authenticationEntry = newAuthenticationEntry; 688 authInfo.authorizationEntry = newAuthorizationEntry; 689 690 authInfo.authenticationTypes.addAll(authenticationTypes); 691 authInfo.saslMechanisms.addAll(saslMechanisms); 692 693 return authInfo; 694 } 695 } 696