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.extensions; 028 029 030 031 import java.util.HashSet; 032 import java.util.List; 033 import java.util.Set; 034 035 import org.opends.messages.Message; 036 import org.opends.server.admin.std.server.WhoAmIExtendedOperationHandlerCfg; 037 import org.opends.server.api.ClientConnection; 038 import org.opends.server.api.ExtendedOperationHandler; 039 import org.opends.server.config.ConfigException; 040 import org.opends.server.controls.ProxiedAuthV1Control; 041 import org.opends.server.controls.ProxiedAuthV2Control; 042 import org.opends.server.core.DirectoryServer; 043 import org.opends.server.core.ExtendedOperation; 044 import org.opends.server.loggers.debug.DebugTracer; 045 import org.opends.server.protocols.asn1.ASN1OctetString; 046 import org.opends.server.types.Control; 047 import org.opends.server.types.DebugLogLevel; 048 import org.opends.server.types.DirectoryException; 049 import org.opends.server.types.DN; 050 import org.opends.server.types.Entry; 051 import org.opends.server.types.InitializationException; 052 import org.opends.server.types.LDAPException; 053 import org.opends.server.types.Privilege; 054 import org.opends.server.types.ResultCode; 055 056 import static org.opends.server.loggers.debug.DebugLogger.*; 057 import static org.opends.messages.ExtensionMessages.*; 058 import static org.opends.server.util.ServerConstants.*; 059 060 061 /** 062 * This class implements the "Who Am I?" extended operation defined in RFC 4532. 063 * It simply returns the authorized ID of the currently-authenticated user. 064 */ 065 public class WhoAmIExtendedOperation 066 extends ExtendedOperationHandler<WhoAmIExtendedOperationHandlerCfg> 067 { 068 /** 069 * The tracer object for the debug logger. 070 */ 071 private static final DebugTracer TRACER = getTracer(); 072 073 074 075 /** 076 * Create an instance of this "Who Am I?" extended operation. All 077 * initialization should be performed in the 078 * <CODE>initializeExtendedOperationHandler</CODE> method. 079 */ 080 public WhoAmIExtendedOperation() 081 { 082 super(); 083 } 084 085 086 /** 087 * Initializes this extended operation handler based on the information in the 088 * provided configuration entry. It should also register itself with the 089 * Directory Server for the particular kinds of extended operations that it 090 * will process. 091 * 092 * @param config The configuration that contains the information 093 * to use to initialize this extended operation handler. 094 * 095 * @throws ConfigException If an unrecoverable problem arises in the 096 * process of performing the initialization. 097 * 098 * @throws InitializationException If a problem occurs during initialization 099 * that is not related to the server 100 * configuration. 101 */ 102 public void initializeExtendedOperationHandler( 103 WhoAmIExtendedOperationHandlerCfg config) 104 throws ConfigException, InitializationException 105 { 106 // No special configuration is required. 107 108 DirectoryServer.registerSupportedExtension(OID_WHO_AM_I_REQUEST, this); 109 110 registerControlsAndFeatures(); 111 } 112 113 114 115 /** 116 * Performs any finalization that may be necessary for this extended 117 * operation handler. By default, no finalization is performed. 118 */ 119 @Override() 120 public void finalizeExtendedOperationHandler() 121 { 122 DirectoryServer.deregisterSupportedExtension(OID_WHO_AM_I_REQUEST); 123 124 deregisterControlsAndFeatures(); 125 } 126 127 128 129 /** 130 * {@inheritDoc} 131 */ 132 @Override() 133 public Set<String> getSupportedControls() 134 { 135 HashSet<String> supportedControls = new HashSet<String>(2); 136 137 supportedControls.add(OID_PROXIED_AUTH_V1); 138 supportedControls.add(OID_PROXIED_AUTH_V2); 139 140 return supportedControls; 141 } 142 143 144 145 /** 146 * {@inheritDoc} 147 */ 148 @Override() 149 public void processExtendedOperation(ExtendedOperation operation) 150 { 151 // Process any supported controls for this operation, including the 152 // proxied authorization control. 153 ClientConnection clientConnection = operation.getClientConnection(); 154 List<Control> requestControls = operation.getRequestControls(); 155 if (requestControls != null) 156 { 157 for (Control c : requestControls) 158 { 159 String oid = c.getOID(); 160 if (oid.equals(OID_PROXIED_AUTH_V1)) 161 { 162 // The requester must have the PROXIED_AUTH privilige in order to 163 // be able to use this control. 164 if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, 165 operation)) 166 { 167 168 operation.appendErrorMessage( 169 ERR_EXTOP_WHOAMI_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get()); 170 operation.setResultCode(ResultCode.AUTHORIZATION_DENIED); 171 return; 172 } 173 174 175 ProxiedAuthV1Control proxyControl; 176 if (c instanceof ProxiedAuthV1Control) 177 { 178 proxyControl = (ProxiedAuthV1Control) c; 179 } 180 else 181 { 182 try 183 { 184 proxyControl = ProxiedAuthV1Control.decodeControl(c); 185 } 186 catch (LDAPException le) 187 { 188 if (debugEnabled()) 189 { 190 TRACER.debugCaught(DebugLogLevel.ERROR, le); 191 } 192 193 operation.setResultCode(ResultCode.valueOf(le.getResultCode())); 194 operation.appendErrorMessage(le.getMessageObject()); 195 return; 196 } 197 } 198 199 200 Entry authorizationEntry; 201 try 202 { 203 authorizationEntry = proxyControl.getAuthorizationEntry(); 204 } 205 catch (DirectoryException de) 206 { 207 if (debugEnabled()) 208 { 209 TRACER.debugCaught(DebugLogLevel.ERROR, de); 210 } 211 212 operation.setResultCode(de.getResultCode()); 213 operation.appendErrorMessage(de.getMessageObject()); 214 return; 215 } 216 217 operation.setAuthorizationEntry(authorizationEntry); 218 } 219 else if (oid.equals(OID_PROXIED_AUTH_V2)) 220 { 221 // The requester must have the PROXIED_AUTH privilige in order to 222 // be able to use this control. 223 if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, 224 operation)) 225 { 226 227 operation.appendErrorMessage( 228 ERR_EXTOP_WHOAMI_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get()); 229 operation.setResultCode(ResultCode.AUTHORIZATION_DENIED); 230 return; 231 } 232 233 234 ProxiedAuthV2Control proxyControl; 235 if (c instanceof ProxiedAuthV2Control) 236 { 237 proxyControl = (ProxiedAuthV2Control) c; 238 } 239 else 240 { 241 try 242 { 243 proxyControl = ProxiedAuthV2Control.decodeControl(c); 244 } 245 catch (LDAPException le) 246 { 247 if (debugEnabled()) 248 { 249 TRACER.debugCaught(DebugLogLevel.ERROR, le); 250 } 251 252 operation.setResultCode(ResultCode.valueOf(le.getResultCode())); 253 operation.appendErrorMessage(le.getMessageObject()); 254 return; 255 } 256 } 257 258 259 Entry authorizationEntry; 260 try 261 { 262 authorizationEntry = proxyControl.getAuthorizationEntry(); 263 } 264 catch (DirectoryException de) 265 { 266 if (debugEnabled()) 267 { 268 TRACER.debugCaught(DebugLogLevel.ERROR, de); 269 } 270 271 operation.setResultCode(de.getResultCode()); 272 operation.appendErrorMessage(de.getMessageObject()); 273 return; 274 } 275 276 operation.setAuthorizationEntry(authorizationEntry); 277 } 278 } 279 } 280 281 282 // Get the authorization DN for the operation and add it to the response 283 // value. 284 String authzID; 285 DN authzDN = operation.getAuthorizationDN(); 286 if (authzDN == null) 287 { 288 authzID = ""; 289 } 290 else 291 { 292 authzID = "dn:" + authzDN.toString(); 293 } 294 295 operation.setResponseValue(new ASN1OctetString(authzID)); 296 operation.appendAdditionalLogMessage( 297 Message.raw("authzID=\"" + authzID + "\"")); 298 operation.setResultCode(ResultCode.SUCCESS); 299 } 300 } 301