001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2006-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2013-2016 ForgeRock AS.
016 */
017package org.opends.server.types;
018
019import org.forgerock.opendj.ldap.ByteString;
020import org.forgerock.opendj.ldap.DN;
021
022import static org.forgerock.util.Reject.*;
023
024/**
025 * This class defines a data structure that may be used to store
026 * information about an authenticated user.  Note that structures in
027 * this class allow for multiple authentication types for the same
028 * user, which is not currently supported by LDAP but may be offered
029 * through some type of extension.
030 */
031@org.opends.server.types.PublicAPI(
032     stability=org.opends.server.types.StabilityLevel.UNCOMMITTED,
033     mayInstantiate=true,
034     mayExtend=false,
035     mayInvoke=true)
036public final class AuthenticationInfo
037{
038  /** Indicates whether this connection is currently authenticated. */
039  private boolean isAuthenticated;
040  /** Indicates whether this connection is authenticated as a root user. */
041  private boolean isRoot;
042  /**
043   * Indicates whether the user's password must be changed before any other
044   * operation will be allowed.
045   */
046  private boolean mustChangePassword;
047
048  /** The entry of the user that is currently authenticated. */
049  private Entry authenticationEntry;
050  /** The entry of the user that will be used as the default authorization identity. */
051  private Entry authorizationEntry;
052  /** The type of authentication performed on this connection. */
053  private AuthenticationType authenticationType;
054  /** The SASL mechanism used to authenticate. */
055  private String saslMechanism;
056  /** The bind DN used to authenticate using simple authentication. */
057  private final DN simpleBindDN;
058
059  /** Creates a new set of authentication information to be used for unauthenticated clients. */
060  public AuthenticationInfo()
061  {
062    isAuthenticated     = false;
063    isRoot              = false;
064    mustChangePassword  = false;
065    authenticationType  = null;
066    authenticationEntry = null;
067    authorizationEntry  = null;
068    simpleBindDN        = null;
069    saslMechanism       = null;
070  }
071
072  /**
073   * Creates a new set of authentication information to be used for
074   * clients that are authenticated internally.
075   *
076   * @param  authenticationEntry  The entry of the user that has
077   *                              authenticated, or {@code null} to
078   *                              indicate an unauthenticated user.
079   * @param  isRoot               Indicates whether the authenticated
080   *                              user is a root user.
081   */
082  public AuthenticationInfo(Entry authenticationEntry, boolean isRoot)
083  {
084    this.authenticationEntry = authenticationEntry;
085    this.isRoot              = isRoot;
086
087    isAuthenticated     = authenticationEntry != null;
088    mustChangePassword  = false;
089    simpleBindDN        = authenticationEntry != null ?
090        authenticationEntry.getName() : null;
091    authorizationEntry  = authenticationEntry;
092    saslMechanism       = null;
093    authenticationType  = AuthenticationType.INTERNAL;
094  }
095
096  /**
097   * Creates a new set of authentication information to be used for
098   * clients that have successfully performed simple authentication.
099   *
100   * @param  authenticationEntry  The entry of the user that has
101   *                              authenticated.  It must not be
102   *                              {@code null}.
103   * @param  simpleBindDN         The bind DN that was used to
104   *                              perform the simple authentication.
105   * @param  isRoot               Indicates whether the authenticated
106   */
107  public AuthenticationInfo(Entry authenticationEntry, DN simpleBindDN,
108      boolean isRoot)
109  {
110    ifNull(authenticationEntry);
111
112    this.authenticationEntry = authenticationEntry;
113    this.simpleBindDN        = simpleBindDN;
114    this.isRoot              = isRoot;
115
116    this.isAuthenticated     = true;
117    this.mustChangePassword  = false;
118    this.authorizationEntry  = authenticationEntry;
119    this.saslMechanism       = null;
120    this.authenticationType  = AuthenticationType.SIMPLE;
121  }
122
123  /**
124   * Creates a new set of authentication information to be used for
125   * clients that have authenticated using a SASL mechanism.
126   *
127   * @param  authenticationEntry  The entry of the user that has
128   *                              authenticated.  It must not be
129   *                              {@code null}.
130   * @param  saslMechanism        The SASL mechanism used to
131   *                              authenticate.  This must be provided
132   *                              in all-uppercase characters and must
133   *                              not be {@code null}.
134   * @param  isRoot               Indicates whether the authenticated
135   *                              user is a root user.
136   */
137  public AuthenticationInfo(Entry authenticationEntry,
138                            String saslMechanism,
139                            boolean isRoot)
140  {
141    ifNull(authenticationEntry, saslMechanism);
142
143    this.authenticationEntry = authenticationEntry;
144    this.isRoot              = isRoot;
145
146    this.isAuthenticated    = true;
147    this.mustChangePassword = false;
148    this.authorizationEntry = authenticationEntry;
149    this.simpleBindDN       = null;
150    this.authenticationType = AuthenticationType.SASL;
151    this.saslMechanism      = saslMechanism;
152  }
153
154  /**
155   * Creates a new set of authentication information to be used for
156   * clients that have authenticated using a SASL mechanism.
157   *
158   * @param  authenticationEntry  The entry of the user that has
159   *                              authenticated.  It must not be
160   *                              {@code null}.
161   * @param  authorizationEntry   The entry of the user that will be
162   *                              used as the default authorization
163   *                              identity, or {@code null} to
164   *                              indicate that the authorization
165   *                              identity should be the
166   *                              unauthenticated user.
167   * @param  saslMechanism        The SASL mechanism used to
168   *                              authenticate.  This must be provided
169   *                              in all-uppercase characters and must
170   *                              not be {@code null}.
171   * @param  saslCredentials      The SASL credentials used to
172   *                              authenticate.
173   *                              It must not be {@code null}.
174   * @param  isRoot               Indicates whether the authenticated
175   *                              user is a root user.
176   */
177  public AuthenticationInfo(Entry authenticationEntry,
178                            Entry authorizationEntry,
179                            String saslMechanism,
180                            ByteString saslCredentials,
181                            boolean isRoot)
182  {
183    ifNull(authenticationEntry, saslMechanism);
184
185    this.authenticationEntry = authenticationEntry;
186    this.authorizationEntry  = authorizationEntry;
187    this.isRoot              = isRoot;
188
189    this.isAuthenticated    = true;
190    this.mustChangePassword = false;
191    this.simpleBindDN       = null;
192    this.authenticationType = AuthenticationType.SASL;
193    this.saslMechanism      = saslMechanism;
194  }
195
196  /**
197   * Indicates whether this client has successfully authenticated to
198   * the server.
199   *
200   * @return  {@code true} if this client has successfully
201   *          authenticated to the server, or {@code false} if not.
202   */
203  public boolean isAuthenticated()
204  {
205    return isAuthenticated;
206  }
207
208  /**
209   * Indicates whether this client should be considered a root user.
210   *
211   * @return  {@code true} if this client should be considered a root
212   *          user, or {@code false} if not.
213   */
214  public boolean isRoot()
215  {
216    return isRoot;
217  }
218
219  /**
220   * Indicates whether the authenticated user must change his/her
221   * password before any other operation will be allowed.
222   *
223   * @return  {@code true} if the user must change his/her password
224   *          before any other operation will be allowed, or
225   *          {@code false} if not.
226   */
227  public boolean mustChangePassword()
228  {
229    return mustChangePassword;
230  }
231
232  /**
233   * Specifies whether the authenticated user must change his/her
234   * password before any other operation will be allowed.
235   *
236   * @param  mustChangePassword  Specifies whether the authenticated
237   *                             user must change his/her password
238   *                             before any other operation will be
239   *                             allowed.
240   */
241  public void setMustChangePassword(boolean mustChangePassword)
242  {
243    this.mustChangePassword = mustChangePassword;
244  }
245
246  /**
247   * Indicates whether this client has authenticated using the
248   * specified authentication type.
249   *
250   * @param  authenticationType  The authentication type for which to
251   *                             make the determination.
252   *
253   * @return  {@code true} if the client has authenticated using the
254   *          specified authentication type, or {@code false} if not.
255   */
256  public boolean hasAuthenticationType(AuthenticationType
257                                            authenticationType)
258  {
259    return this.authenticationType == authenticationType;
260  }
261
262  /**
263   * Retrieves the entry for the user as whom the client is
264   * authenticated.
265   *
266   * @return  The entry for the user as whom the client is
267   *          authenticated, or {@code null} if the client is
268   *          unauthenticated.
269   */
270  public Entry getAuthenticationEntry()
271  {
272    return authenticationEntry;
273  }
274
275  /**
276   * Retrieves the DN of the user as whom the client is authenticated.
277   *
278   * @return  The DN of the user as whom the client is authenticated,
279   *          or {@code null} if the client is unauthenticated.
280   */
281  public DN getAuthenticationDN()
282  {
283    if (authenticationEntry != null)
284    {
285      return authenticationEntry.getName();
286    }
287    return null;
288  }
289
290  /**
291   * Sets the DN of the user as whom the client is authenticated,
292   * does nothing if the client is unauthenticated.
293   *
294   * @param dn authentication identity DN.
295   */
296  public void setAuthenticationDN(DN dn)
297  {
298    if (authenticationEntry != null)
299    {
300      authenticationEntry.setDN(dn);
301    }
302  }
303
304  /**
305   * Retrieves the entry for the user that should be used as the
306   * default authorization identity.
307   *
308   * @return  The entry for the user that should be used as the
309   *          default authorization identity, or {@code null} if the
310   *          authorization identity should be the unauthenticated
311   *          user.
312   */
313  public Entry getAuthorizationEntry()
314  {
315    return authorizationEntry;
316  }
317
318  /**
319   * Retrieves the DN for the user that should be used as the default
320   * authorization identity.
321   *
322   * @return  The DN for the user that should be used as the default
323   *          authorization identity, or {@code null} if the
324   *          authorization identity should be the unauthenticated
325   *          user.
326   */
327  public DN getAuthorizationDN()
328  {
329    if (authorizationEntry != null)
330    {
331      return authorizationEntry.getName();
332    }
333    return null;
334  }
335
336  /**
337   * Sets the DN for the user that should be used as the default
338   * authorization identity, does nothing if the client is
339   * unauthorized.
340   *
341   * @param dn authorization identity DN.
342   */
343  public void setAuthorizationDN(DN dn)
344  {
345    if (authorizationEntry != null)
346    {
347      authorizationEntry.setDN(dn);
348    }
349  }
350
351  /**
352   * Retrieves the bind DN that the client used for simple
353   * authentication.
354   *
355   * @return  The bind DN that the client used for simple
356   *          authentication, or {@code null} if the client is not
357   *          authenticated using simple authentication.
358   */
359  public DN getSimpleBindDN()
360  {
361    return simpleBindDN;
362  }
363
364  /**
365   * Indicates whether the client is currently authenticated using the
366   * specified SASL mechanism.
367   *
368   * @param  saslMechanism  The SASL mechanism for which to make the
369   *                        determination.  Note that this must be
370   *                        provided in all uppercase characters.
371   *
372   * @return  {@code true} if the client is authenticated using the
373   *          specified SASL mechanism, or {@code false} if not.
374   */
375  public boolean hasSASLMechanism(String saslMechanism)
376  {
377    return this.saslMechanism.equals(saslMechanism);
378  }
379
380  /**
381   * Retrieves a string representation of this authentication info
382   * structure.
383   *
384   * @return  A string representation of this authentication info
385   *          structure.
386   */
387  @Override
388  public String toString()
389  {
390    StringBuilder buffer = new StringBuilder();
391    toString(buffer);
392
393    return buffer.toString();
394  }
395
396  /**
397   * Appends a string representation of this authentication info
398   * structure to the provided buffer.
399   *
400   * @param  buffer  The buffer to which the information is to be
401   *                 appended.
402   */
403  private void toString(StringBuilder buffer)
404  {
405    buffer.append("AuthenticationInfo(isAuthenticated=");
406    buffer.append(isAuthenticated);
407    buffer.append(",isRoot=");
408    buffer.append(isRoot);
409    buffer.append(",mustChangePassword=");
410    buffer.append(mustChangePassword);
411    buffer.append(",authenticationDN=\"");
412
413    if (authenticationEntry != null)
414    {
415      buffer.append(authenticationEntry.getName());
416    }
417
418    if (authorizationEntry == null)
419    {
420      buffer.append("\",authorizationDN=\"\"");
421    }
422    else
423    {
424      buffer.append("\",authorizationDN=\"");
425      buffer.append(authorizationEntry.getName());
426      buffer.append("\"");
427    }
428
429    if (authenticationType != null)
430    {
431      buffer.append(",authType=");
432      buffer.append(authenticationType);
433    }
434
435    if (saslMechanism != null)
436    {
437      buffer.append(",saslMechanism=");
438      buffer.append(saslMechanism);
439    }
440
441    buffer.append(")");
442  }
443
444  /**
445   * Creates a duplicate of this {@code AuthenticationInfo} object
446   * with the new authentication and authorization entries.
447   *
448   * @param  newAuthenticationEntry  The updated entry for the user
449   *                                 as whom the associated client
450   *                                 connection is authenticated.
451   * @param  newAuthorizationEntry   The updated entry for the default
452   *                                 authorization identity for the
453   *                                 associated client connection.
454   *
455   * @return  The duplicate of this {@code AuthenticationInfo} object
456   *          with the specified authentication and authorization
457   *          entries.
458   */
459  public AuthenticationInfo duplicate(Entry newAuthenticationEntry,
460                                      Entry newAuthorizationEntry)
461  {
462    AuthenticationInfo authInfo = new AuthenticationInfo();
463
464    authInfo.isAuthenticated     = isAuthenticated;
465    authInfo.isRoot              = isRoot;
466    authInfo.mustChangePassword  = mustChangePassword;
467    authInfo.authenticationEntry = newAuthenticationEntry;
468    authInfo.authorizationEntry  = newAuthorizationEntry;
469
470    authInfo.authenticationType  = authenticationType;
471    authInfo.saslMechanism       = saslMechanism;
472
473    return authInfo;
474  }
475}