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