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