001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.server.core.api; 021 022 023import java.net.SocketAddress; 024import java.security.Principal; 025 026import org.apache.directory.api.ldap.model.constants.AuthenticationLevel; 027import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; 028import org.apache.directory.api.ldap.model.name.Dn; 029import org.apache.directory.api.ldap.model.schema.SchemaManager; 030import org.apache.directory.server.i18n.I18n; 031 032 033/** 034 * An alternative X500 user implementation that has access to the distinguished 035 * name of the principal as well as the String representation. 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 */ 039public final class LdapPrincipal implements Principal, Cloneable 040{ 041 /** the normalized distinguished name of the principal */ 042 private Dn dn = Dn.EMPTY_DN; 043 044 /** the authentication level for this principal */ 045 private AuthenticationLevel authenticationLevel; 046 047 /** The userPassword 048 * @todo security risk remove this immediately 049 */ 050 private byte[][] userPasswords; 051 052 /** The SchemaManager */ 053 private SchemaManager schemaManager; 054 055 private SocketAddress clientAddress; 056 private SocketAddress serverAddress; 057 058 059 /** 060 * Creates a new LDAP/X500 principal without any group associations. Keep 061 * this package friendly so only code in the package can create a 062 * trusted principal. 063 * 064 * @param schemaManager The SchemaManager 065 * @param dn the normalized distinguished name of the principal 066 * @param authenticationLevel the authentication level for this principal 067 */ 068 public LdapPrincipal( SchemaManager schemaManager, Dn dn, AuthenticationLevel authenticationLevel ) 069 { 070 this.schemaManager = schemaManager; 071 this.dn = dn; 072 073 if ( !dn.isSchemaAware() ) 074 { 075 throw new IllegalStateException( I18n.err( I18n.ERR_436 ) ); 076 } 077 078 this.authenticationLevel = authenticationLevel; 079 this.userPasswords = null; 080 } 081 082 083 /** 084 * Creates a new LDAP/X500 principal without any group associations. Keep 085 * this package friendly so only code in the package can create a 086 * trusted principal. 087 * 088 * @param schemaManager The SchemaManager 089 * @param dn the normalized distinguished name of the principal 090 * @param authenticationLevel the authentication level for this principal 091 * @param userPassword The user password 092 */ 093 public LdapPrincipal( SchemaManager schemaManager, Dn dn, AuthenticationLevel authenticationLevel, 094 byte[] userPassword ) 095 { 096 this.dn = dn; 097 this.authenticationLevel = authenticationLevel; 098 this.userPasswords = new byte[1][]; 099 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 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}