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.forgerock.opendj.server.config.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 @Override 058 public void initializeExtendedOperationHandler( 059 WhoAmIExtendedOperationHandlerCfg config) 060 throws ConfigException, InitializationException 061 { 062 super.initializeExtendedOperationHandler(config); 063 } 064 065 @Override 066 public void processExtendedOperation(ExtendedOperation operation) 067 { 068 // Process any supported controls for this operation, including the 069 // proxied authorization control. 070 ClientConnection clientConnection = operation.getClientConnection(); 071 Entry authorizationEntry; 072 try 073 { 074 ProxiedAuthV1Control proxyControlV1 = 075 operation.getRequestControl(ProxiedAuthV1Control.DECODER); 076 ProxiedAuthV2Control proxyControlV2 = 077 operation.getRequestControl(ProxiedAuthV2Control.DECODER); 078 if(proxyControlV1 != null || proxyControlV2 != null) 079 { 080 // The requester must have the PROXIED_AUTH privilege in order to be 081 // able to use this control. 082 if (! clientConnection.hasPrivilege(Privilege.PROXIED_AUTH, 083 operation)) 084 { 085 operation.appendErrorMessage( 086 ERR_EXTOP_WHOAMI_PROXYAUTH_INSUFFICIENT_PRIVILEGES.get()); 087 operation.setResultCode(ResultCode.AUTHORIZATION_DENIED); 088 return; 089 } 090 091 if(proxyControlV2 != null) 092 { 093 authorizationEntry = proxyControlV2.getAuthorizationEntry(); 094 } 095 else 096 { 097 // Log usage of legacy proxy authz V1 control. 098 operation.addAdditionalLogItem(AdditionalLogItem.keyOnly(getClass(), 099 "obsoleteProxiedAuthzV1Control")); 100 101 authorizationEntry = proxyControlV1.getAuthorizationEntry(); 102 } 103 // Check the requester has the authz user in scope of their proxy aci. 104 if (! AccessControlConfigManager.getInstance().getAccessControlHandler() 105 .mayProxy(clientConnection.getAuthenticationInfo().getAuthenticationEntry(), 106 authorizationEntry, operation)) 107 { 108 final DN dn = authorizationEntry.getName(); 109 throw new DirectoryException(ResultCode.AUTHORIZATION_DENIED, 110 ERR_PROXYAUTH_AUTHZ_NOT_PERMITTED.get(dn)); 111 } 112 operation.setAuthorizationEntry(authorizationEntry); 113 } 114 } 115 catch (DirectoryException de) 116 { 117 logger.traceException(de); 118 119 operation.setResultCode(de.getResultCode()); 120 operation.appendErrorMessage(de.getMessageObject()); 121 return; 122 } 123 124 // Get the authorization DN for the operation and add it to the response 125 // value. 126 String authzID; 127 DN authzDN = operation.getAuthorizationDN(); 128 if (authzDN == null) 129 { 130 authzID = ""; 131 } 132 else 133 { 134 authzID = "dn:" + authzDN; 135 } 136 137 operation.setResponseValue(ByteString.valueOfUtf8(authzID)); 138 operation.addAdditionalLogItem(AdditionalLogItem.quotedKeyValue( 139 getClass(), "authzID", authzID)); 140 operation.setResultCode(ResultCode.SUCCESS); 141 } 142 143 @Override 144 public String getExtendedOperationOID() 145 { 146 return OID_WHO_AM_I_REQUEST; 147 } 148 149 @Override 150 public String getExtendedOperationName() 151 { 152 return "Who Am I?"; 153 } 154}