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.interceptor.context; 021 022 023import org.apache.commons.lang3.NotImplementedException; 024import org.apache.directory.api.ldap.model.constants.AuthenticationLevel; 025import org.apache.directory.api.ldap.model.entry.Entry; 026import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException; 027import org.apache.directory.api.ldap.model.message.MessageTypeEnum; 028import org.apache.directory.api.ldap.model.name.Dn; 029import org.apache.directory.api.util.Strings; 030import org.apache.directory.server.core.api.CoreSession; 031import org.apache.directory.server.core.api.OperationEnum; 032import org.apache.directory.server.core.api.ReferralHandlingMode; 033import org.apache.directory.server.i18n.I18n; 034import org.apache.mina.core.session.IoSession; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038 039/** 040 * A Bind context used for Interceptors. It contains all the informations 041 * needed for the bind operation, and used by all the interceptors 042 * 043 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 044 */ 045public class BindOperationContext extends AbstractOperationContext 046{ 047 /** A logger for this class */ 048 private static final Logger LOG = LoggerFactory.getLogger( BindOperationContext.class ); 049 050 /** The password */ 051 private byte[] credentials; 052 053 /** The SASL mechanism */ 054 private String saslMechanism; 055 056 /** The SASL identifier */ 057 private String saslAuthId; 058 059 /** A flag to tell that this is a collateral operation */ 060 private boolean collateralOperation; 061 062 private ReferralHandlingMode referralHandlingMode; 063 064 /** The IoSession if any */ 065 private IoSession ioSession; 066 067 /** The LDAP Principal */ 068 private Entry principal; 069 070 071 /** 072 * Creates a new instance of BindOperationContext. 073 * 074 * @param session The session to use 075 */ 076 public BindOperationContext( CoreSession session ) 077 { 078 super( session ); 079 080 if ( session != null ) 081 { 082 setInterceptors( session.getDirectoryService().getInterceptors( OperationEnum.BIND ) ); 083 } 084 } 085 086 087 /** 088 * @return The authentication level. One of : 089 * <ul> 090 * <li>ANONYMOUS</li> 091 * <li>SIMPLE</li> 092 * <li>STRONG (sasl)</li> 093 * <li>UNAUTHENT</li> 094 * <li>INVALID</li> 095 * </ul> 096 * @throws LdapAuthenticationException If we can't get the AuthenticationLevel 097 */ 098 public AuthenticationLevel getAuthenticationLevel() throws LdapAuthenticationException 099 { 100 // First check if the SASL mechanism has been set 101 if ( saslMechanism == null ) 102 { 103 // No, it's either a SIMPLE, ANONYMOUS, UNAUTHENT or an error 104 // 105 if ( Dn.isNullOrEmpty( dn ) ) 106 { 107 if ( Strings.isEmpty( credentials ) ) 108 { 109 // Dn and Credentials are empty, this is an anonymous authent 110 return AuthenticationLevel.NONE; 111 } 112 else 113 { 114 // If we have a password but no Dn, this is invalid 115 LOG.info( "Bad authentication for {}", dn ); 116 throw new LdapAuthenticationException( "Invalid authentication" ); 117 } 118 } 119 else if ( Strings.isEmpty( credentials ) ) 120 { 121 return AuthenticationLevel.UNAUTHENT; 122 } 123 else 124 { 125 return AuthenticationLevel.SIMPLE; 126 } 127 } 128 else 129 { 130 return AuthenticationLevel.STRONG; 131 } 132 } 133 134 135 /** 136 * @return the SASL mechanisms 137 */ 138 public String getSaslMechanism() 139 { 140 return saslMechanism; 141 } 142 143 144 public void setSaslMechanism( String saslMechanism ) 145 { 146 this.saslMechanism = saslMechanism; 147 } 148 149 150 /** 151 * @return The principal password 152 */ 153 public byte[] getCredentials() 154 { 155 return credentials; 156 } 157 158 159 public void setCredentials( byte[] credentials ) 160 { 161 this.credentials = credentials; 162 } 163 164 165 /** 166 * @return The SASL authentication ID 167 */ 168 public String getSaslAuthId() 169 { 170 return saslAuthId; 171 } 172 173 174 public void setSaslAuthId( String saslAuthId ) 175 { 176 this.saslAuthId = saslAuthId; 177 } 178 179 180 public boolean isSaslBind() 181 { 182 return saslMechanism != null; 183 } 184 185 186 /** 187 * @return the operation name 188 */ 189 @Override 190 public String getName() 191 { 192 return MessageTypeEnum.BIND_REQUEST.name(); 193 } 194 195 196 /** 197 * @see Object#toString() 198 */ 199 @Override 200 public String toString() 201 { 202 return "BindContext for Dn '" + getDn().getName() 203 + ( saslMechanism != null ? ", saslMechanism : <" + saslMechanism + ">" : "" ) 204 + ( saslAuthId != null ? ", saslAuthId <" + saslAuthId + ">" : "" ); 205 } 206 207 208 /** 209 * Tells if the current operation is considered a side effect of the 210 * current context 211 * 212 * @return <tt>true</tt> if there is no collateral operation 213 */ 214 public boolean isCollateralOperation() 215 { 216 return collateralOperation; 217 } 218 219 220 public void setCollateralOperation( boolean collateralOperation ) 221 { 222 this.collateralOperation = collateralOperation; 223 } 224 225 226 public ReferralHandlingMode getReferralHandlingMode() 227 { 228 return referralHandlingMode; 229 } 230 231 232 public void setReferralHandlingMode( ReferralHandlingMode referralHandlingMode ) 233 { 234 this.referralHandlingMode = referralHandlingMode; 235 } 236 237 238 /** 239 * {@inheritDoc} 240 */ 241 @Override 242 public void throwReferral() 243 { 244 throw new NotImplementedException( I18n.err( I18n.ERR_320 ) ); 245 } 246 247 248 /** 249 * {@inheritDoc} 250 */ 251 @Override 252 public boolean isReferralThrown() 253 { 254 throw new NotImplementedException( I18n.err( I18n.ERR_321 ) ); 255 } 256 257 258 /** 259 * {@inheritDoc} 260 */ 261 @Override 262 public void ignoreReferral() 263 { 264 throw new NotImplementedException( I18n.err( I18n.ERR_322 ) ); 265 } 266 267 268 /** 269 * {@inheritDoc} 270 */ 271 @Override 272 public boolean isReferralIgnored() 273 { 274 throw new NotImplementedException( I18n.err( I18n.ERR_323 ) ); 275 } 276 277 278 /** 279 * @return the ioSession 280 */ 281 public IoSession getIoSession() 282 { 283 return ioSession; 284 } 285 286 287 /** 288 * @param ioSession the ioSession to set 289 */ 290 public void setIoSession( IoSession ioSession ) 291 { 292 this.ioSession = ioSession; 293 } 294 295 296 /** 297 * @return the principal 298 */ 299 public Entry getPrincipal() 300 { 301 return principal; 302 } 303 304 305 /** 306 * @param principal the principal to set 307 */ 308 public void setPrincipal( Entry principal ) 309 { 310 this.principal = principal; 311 } 312}