View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.core.api;
21  
22  
23  import java.net.SocketAddress;
24  import java.security.Principal;
25  
26  import org.apache.directory.api.ldap.model.constants.AuthenticationLevel;
27  import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
28  import org.apache.directory.api.ldap.model.name.Dn;
29  import org.apache.directory.api.ldap.model.schema.SchemaManager;
30  import org.apache.directory.server.i18n.I18n;
31  
32  
33  /**
34   * An alternative X500 user implementation that has access to the distinguished
35   * name of the principal as well as the String representation.
36   *
37   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
38   */
39  public final class LdapPrincipal implements Principal, Cloneable
40  {
41      /** the normalized distinguished name of the principal */
42      private Dn dn = Dn.EMPTY_DN;
43  
44      /** the authentication level for this principal */
45      private AuthenticationLevel authenticationLevel;
46  
47      /** The userPassword
48       * @todo security risk remove this immediately
49       */
50      private byte[][] userPasswords;
51  
52      /** The SchemaManager */
53      private SchemaManager schemaManager;
54  
55      private SocketAddress clientAddress;
56      private SocketAddress serverAddress;
57  
58  
59      /**
60       * Creates a new LDAP/X500 principal without any group associations.  Keep
61       * this package friendly so only code in the package can create a
62       * trusted principal.
63       *
64       * @param schemaManager The SchemaManager
65       * @param dn the normalized distinguished name of the principal
66       * @param authenticationLevel the authentication level for this principal
67       */
68      public LdapPrincipal( SchemaManager schemaManager, Dn dn, AuthenticationLevel authenticationLevel )
69      {
70          this.schemaManager = schemaManager;
71          this.dn = dn;
72  
73          if ( !dn.isSchemaAware() )
74          {
75              throw new IllegalStateException( I18n.err( I18n.ERR_436 ) );
76          }
77  
78          this.authenticationLevel = authenticationLevel;
79          this.userPasswords = null;
80      }
81  
82  
83      /**
84       * Creates a new LDAP/X500 principal without any group associations.  Keep
85       * this package friendly so only code in the package can create a
86       * trusted principal.
87       *
88       * @param schemaManager The SchemaManager
89       * @param dn the normalized distinguished name of the principal
90       * @param authenticationLevel the authentication level for this principal
91       * @param userPassword The user password
92       */
93      public LdapPrincipal( SchemaManager schemaManager, Dn dn, AuthenticationLevel authenticationLevel,
94          byte[] userPassword )
95      {
96          this.dn = dn;
97          this.authenticationLevel = authenticationLevel;
98          this.userPasswords = new byte[1][];
99          this.userPasswords[0] = new byte[userPassword.length];
100         System.arraycopy( userPassword, 0, this.userPasswords[0], 0, userPassword.length );
101         this.schemaManager = schemaManager;
102     }
103 
104 
105     /**
106      * Creates a principal for the no name anonymous user whose Dn is the empty
107      * String.
108      */
109     public LdapPrincipal()
110     {
111         authenticationLevel = AuthenticationLevel.NONE;
112         userPasswords = null;
113     }
114 
115 
116     /**
117      * Creates a principal for the no name anonymous user whose Dn is the empty
118      * String.
119      * 
120      * @param schemaManager The SchemaManager
121      */
122     public LdapPrincipal( SchemaManager schemaManager )
123     {
124         authenticationLevel = AuthenticationLevel.NONE;
125         userPasswords = null;
126         this.schemaManager = schemaManager;
127     }
128 
129 
130     /**
131      * Gets a cloned copy of the normalized distinguished name of this
132      * principal as a {@link org.apache.directory.api.ldap.model.name.Dn}.
133      *
134      * @return the cloned distinguished name of the principal as a {@link org.apache.directory.api.ldap.model.name.Dn}
135      */
136     public Dn getDn()
137     {
138         return dn;
139     }
140 
141 
142     /**
143      * Returns the normalized distinguished name of the principal as a String.
144      */
145     @Override
146     public String getName()
147     {
148         return dn.getNormName();
149     }
150 
151 
152     /**
153      * Gets the authentication level associated with this LDAP principle.
154      *
155      * @return the authentication level
156      */
157     public AuthenticationLevel getAuthenticationLevel()
158     {
159         return authenticationLevel;
160     }
161 
162 
163     public byte[][] getUserPasswords()
164     {
165         return userPasswords;
166     }
167 
168 
169     public void setUserPassword( byte[]... userPasswords )
170     {
171         this.userPasswords = new byte[userPasswords.length][];
172         int pos = 0;
173 
174         for ( byte[] userPassword : userPasswords )
175         {
176             this.userPasswords[pos] = new byte[userPassword.length];
177             System.arraycopy( userPassword, 0, this.userPasswords[pos], 0, userPassword.length );
178             pos++;
179         }
180     }
181 
182 
183     /**
184      * Clone the object. This is done so that we don't store the 
185      * password in a LdapPrincipal more than necessary.
186      */
187     @Override
188     public Object clone() throws CloneNotSupportedException
189     {
190         LdapPrincipal./../../../org/apache/directory/server/core/api/LdapPrincipal.html#LdapPrincipal">LdapPrincipal clone = ( LdapPrincipal ) super.clone();
191 
192         if ( userPasswords != null )
193         {
194             clone.setUserPassword( userPasswords );
195         }
196 
197         return clone;
198     }
199 
200 
201     /**
202      * @return the schemaManager
203      */
204     public SchemaManager getSchemaManager()
205     {
206         return schemaManager;
207     }
208 
209 
210     /**
211      * @param schemaManager the schemaManager to set
212      */
213     public void setSchemaManager( SchemaManager schemaManager )
214     {
215         this.schemaManager = schemaManager;
216 
217         if ( !dn.isSchemaAware() )
218         {
219             try
220             {
221                 dn = new Dn( schemaManager, dn );
222             }
223             catch ( LdapInvalidDnException lide )
224             {
225                 // TODO: manage this exception
226             }
227         }
228     }
229 
230 
231     /**
232      * @return the clientAddress
233      */
234     public SocketAddress getClientAddress()
235     {
236         return clientAddress;
237     }
238 
239 
240     /**
241      * @param clientAddress the clientAddress to set
242      */
243     public void setClientAddress( SocketAddress clientAddress )
244     {
245         this.clientAddress = clientAddress;
246     }
247 
248 
249     /**
250      * @return the serverAddress
251      */
252     public SocketAddress getServerAddress()
253     {
254         return serverAddress;
255     }
256 
257 
258     /**
259      * @param serverAddress the serverAddress to set
260      */
261     public void setServerAddress( SocketAddress serverAddress )
262     {
263         this.serverAddress = serverAddress;
264     }
265 
266 
267     /**
268      * Returns string representation of the normalized distinguished name
269      * of this principal.
270      */
271     @Override
272     public String toString()
273     {
274         StringBuilder sb = new StringBuilder();
275 
276         if ( dn.isSchemaAware() )
277         {
278             sb.append( "(n)" );
279         }
280 
281         sb.append( "['" );
282         sb.append( dn.getName() );
283         sb.append( "'" );
284 
285         if ( clientAddress != null )
286         {
287             sb.append( ", client@" );
288             sb.append( clientAddress );
289         }
290 
291         if ( serverAddress != null )
292         {
293             sb.append( ", server@" );
294             sb.append( serverAddress );
295         }
296 
297         sb.append( "]" );
298 
299         return sb.toString();
300     }
301 }