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-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2011-2016 ForgeRock AS. 016 */ 017package org.opends.server.extensions; 018 019import static org.opends.messages.ExtensionMessages.*; 020import static org.opends.messages.ProtocolMessages.*; 021import static org.opends.server.util.CollectionUtils.*; 022import static org.opends.server.util.ServerConstants.*; 023 024import org.forgerock.i18n.slf4j.LocalizedLogger; 025import org.forgerock.opendj.config.server.ConfigException; 026import org.forgerock.opendj.ldap.ByteString; 027import org.forgerock.opendj.ldap.DN; 028import org.forgerock.opendj.ldap.ResultCode; 029import org.opends.server.admin.std.server.WhoAmIExtendedOperationHandlerCfg; 030import org.opends.server.api.ClientConnection; 031import org.opends.server.api.ExtendedOperationHandler; 032import org.opends.server.controls.ProxiedAuthV1Control; 033import org.opends.server.controls.ProxiedAuthV2Control; 034import org.opends.server.core.AccessControlConfigManager; 035import org.opends.server.core.ExtendedOperation; 036import org.opends.server.types.*; 037 038/** 039 * This class implements the "Who Am I?" extended operation defined in RFC 4532. 040 * It simply returns the authorized ID of the currently-authenticated user. 041 */ 042public class WhoAmIExtendedOperation 043 extends ExtendedOperationHandler<WhoAmIExtendedOperationHandlerCfg> 044{ 045 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 046 047 /** 048 * Create an instance of this "Who Am I?" extended operation. All 049 * initialization should be performed in the 050 * <CODE>initializeExtendedOperationHandler</CODE> method. 051 */ 052 public WhoAmIExtendedOperation() 053 { 054 super(newHashSet(OID_PROXIED_AUTH_V1, OID_PROXIED_AUTH_V2)); 055 } 056 057 /** {@inheritDoc} */ 058 @Override 059 public void initializeExtendedOperationHandler( 060 WhoAmIExtendedOperationHandlerCfg config) 061 throws ConfigException, InitializationException 062 { 063 super.initializeExtendedOperationHandler(config); 064 } 065 066 /** {@inheritDoc} */ 067 @Override 068 public void processExtendedOperation(ExtendedOperation operation) 069 { 070 // Process any supported controls for this operation, including the 071 // proxied authorization control. 072 ClientConnection clientConnection = operation.getClientConnection(); 073 Entry authorizationEntry; 074 try 075 { 076 ProxiedAuthV1Control proxyControlV1 = 077 operation.getRequestControl(ProxiedAuthV1Control.DECODER); 078 ProxiedAuthV2Control proxyControlV2 = 079 operation.getRequestControl(ProxiedAuthV2Control.DECODER); 080 if(proxyControlV1 != null || proxyControlV2 != null) 081 { 082 // The requester must have the PROXIED_AUTH privilege in order to be 083 // able to use this control. 084 if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, 085 operation)) 086 { 087 operation.appendErrorMessage( 088 ERR_EXTOP_WHOAMI_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get()); 089 operation.setResultCode(ResultCode.AUTHORIZATION_DENIED); 090 return; 091 } 092 093 if(proxyControlV2 != null) 094 { 095 authorizationEntry = proxyControlV2.getAuthorizationEntry(); 096 } 097 else 098 { 099 // Log usage of legacy proxy authz V1 control. 100 operation.addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(), 101 "obsoleteProxiedAuthzV1Control")); 102 103 authorizationEntry = proxyControlV1.getAuthorizationEntry(); 104 } 105 // Check the requester has the authz user in scope of their proxy aci. 106 if (! AccessControlConfigManager.getInstance().getAccessControlHandler() 107 .mayProxy(clientConnection.getAuthenticationInfo().getAuthenticationEntry(), 108 authorizationEntry, operation)) 109 { 110 final DN dn = authorizationEntry.getName(); 111 throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, 112 ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED.get(dn)); 113 } 114 operation.setAuthorizationEntry(authorizationEntry); 115 } 116 } 117 catch (DirectoryException de) 118 { 119 logger.traceException(de); 120 121 operation.setResultCode(de.getResultCode()); 122 operation.appendErrorMessage(de.getMessageObject()); 123 return; 124 } 125 126 127 // Get the authorization DN for the operation and add it to the response 128 // value. 129 String authzID; 130 DN authzDN = operation.getAuthorizationDN(); 131 if (authzDN == null) 132 { 133 authzID = ""; 134 } 135 else 136 { 137 authzID = "dn:" + authzDN; 138 } 139 140 operation.setResponseValue(ByteString.valueOfUtf8(authzID)); 141 operation.addAdditionalLogItem(AdditionalLogItem.quotedKeyValue( 142 getClass(), "authzID", authzID)); 143 operation.setResultCode(ResultCode.SUCCESS); 144 } 145 146 /** {@inheritDoc} */ 147 @Override 148 public String getExtendedOperationOID() 149 { 150 return OID_WHO_AM_I_REQUEST; 151 } 152 153 /** {@inheritDoc} */ 154 @Override 155 public String getExtendedOperationName() 156 { 157 return "Who Am I?"; 158 } 159}