001/* 002 * Copyright 2007-2022 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2007-2022 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2007-2022 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk.controls; 037 038 039 040import com.unboundid.asn1.ASN1OctetString; 041import com.unboundid.ldap.sdk.Control; 042import com.unboundid.ldap.sdk.LDAPException; 043import com.unboundid.ldap.sdk.ResultCode; 044import com.unboundid.util.NotMutable; 045import com.unboundid.util.NotNull; 046import com.unboundid.util.ThreadSafety; 047import com.unboundid.util.ThreadSafetyLevel; 048import com.unboundid.util.Validator; 049 050import static com.unboundid.ldap.sdk.controls.ControlMessages.*; 051 052 053 054/** 055 * This class provides an implementation of the proxied authorization V2 056 * request control, as defined in 057 * <A HREF="http://www.ietf.org/rfc/rfc4370.txt">RFC 4370</A>. It may be used 058 * to request that the associated operation be performed as if it has been 059 * requested by some other user. 060 * <BR><BR> 061 * The target authorization identity for this control is specified as an 062 * "authzId" value as described in section 5.2.1.8 of 063 * <A HREF="http://www.ietf.org/rfc/rfc4513.txt">RFC 4513</A>. That is, it 064 * should be either "dn:" followed by the distinguished name of the target user, 065 * or "u:" followed by the username. If the "u:" form is used, then the 066 * mechanism used to resolve the provided username to an entry may vary from 067 * server to server. 068 * <BR><BR> 069 * This control may be used in conjunction with add, delete, compare, delete, 070 * extended, modify, modify DN, and search requests. In that case, the 071 * associated operation will be processed under the authority of the specified 072 * authorization identity rather than the identity associated with the client 073 * connection (i.e., the user as whom that connection is bound). Note that 074 * because of the inherent security risks associated with the use of the proxied 075 * authorization control, most directory servers which support its use enforce 076 * strict restrictions on the users that are allowed to request this control. 077 * If a user attempts to use the proxied authorization V2 request control and 078 * does not have sufficient permission to do so, then the server will return a 079 * failure response with the {@link ResultCode#AUTHORIZATION_DENIED} result 080 * code. 081 * <BR><BR> 082 * There is no corresponding response control for this request control. 083 * <BR><BR> 084 * <H2>Example</H2> 085 * The following example demonstrates the use of the proxied authorization V2 086 * control to delete an entry under the authority of the user with username 087 * "alternate.user": 088 * <PRE> 089 * // Create a delete request to delete an entry. Include the proxied 090 * // authorization v2 request control in the delete request so that the 091 * // delete will be processed as the user with username "alternate.user" 092 * // instead of the user that's actually authenticated on the connection. 093 * DeleteRequest deleteRequest = 094 * new DeleteRequest("uid=test.user,ou=People,dc=example,dc=com"); 095 * deleteRequest.addControl(new ProxiedAuthorizationV2RequestControl( 096 * "u:alternate.user")); 097 * 098 * LDAPResult deleteResult; 099 * try 100 * { 101 * deleteResult = connection.delete(deleteRequest); 102 * // If we got here, then the delete was successful. 103 * } 104 * catch (LDAPException le) 105 * { 106 * // The delete failed for some reason. In addition to all of the normal 107 * // reasons a delete could fail (e.g., the entry doesn't exist, or has one 108 * // or more subordinates), proxied-authorization specific failures may 109 * // include that the authenticated user doesn't have permission to use the 110 * // proxied authorization control to impersonate the alternate user, that 111 * // the alternate user doesn't exist, or that the alternate user doesn't 112 * // have permission to perform the requested operation. 113 * deleteResult = le.toLDAPResult(); 114 * ResultCode resultCode = le.getResultCode(); 115 * String errorMessageFromServer = le.getDiagnosticMessage(); 116 * } 117 * </PRE> 118 */ 119@NotMutable() 120@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 121public final class ProxiedAuthorizationV2RequestControl 122 extends Control 123{ 124 /** 125 * The OID (2.16.840.1.113730.3.4.18) for the proxied authorization v2 request 126 * control. 127 */ 128 @NotNull public static final String PROXIED_AUTHORIZATION_V2_REQUEST_OID = 129 "2.16.840.1.113730.3.4.18"; 130 131 132 133 /** 134 * The serial version UID for this serializable class. 135 */ 136 private static final long serialVersionUID = 1054244283964851067L; 137 138 139 140 // The authorization ID string that may be used to identify the user under 141 // whose authorization the associated operation should be performed. 142 @NotNull private final String authorizationID; 143 144 145 146 /** 147 * Creates a new proxied authorization V2 request control that will proxy as 148 * the specified user. 149 * 150 * @param authorizationID The authorization ID string that will be used to 151 * identify the user under whose authorization the 152 * associated operation should be performed. It may 153 * take one of three forms: it can be an empty 154 * string (to indicate that the operation should use 155 * anonymous authorization), a string that begins 156 * with "dn:" and is followed by the DN of the target 157 * user, or a string that begins with "u:" and is 158 * followed by the username for the target user 159 * (where the process of mapping the provided 160 * username to the corresponding entry will depend on 161 * the server configuration). It must not be 162 * {@code null}. 163 */ 164 public ProxiedAuthorizationV2RequestControl( 165 @NotNull final String authorizationID) 166 { 167 super(PROXIED_AUTHORIZATION_V2_REQUEST_OID, true, 168 new ASN1OctetString(authorizationID)); 169 170 Validator.ensureNotNull(authorizationID); 171 172 this.authorizationID = authorizationID; 173 } 174 175 176 177 /** 178 * Creates a new proxied authorization v2 request control which is decoded 179 * from the provided generic control. 180 * 181 * @param control The generic control to be decoded as a proxied 182 * authorization v2 request control. 183 * 184 * @throws LDAPException If the provided control cannot be decoded as a 185 * proxied authorization v2 request control. 186 */ 187 public ProxiedAuthorizationV2RequestControl(@NotNull final Control control) 188 throws LDAPException 189 { 190 super(control); 191 192 final ASN1OctetString value = control.getValue(); 193 if (value == null) 194 { 195 throw new LDAPException(ResultCode.DECODING_ERROR, 196 ERR_PROXY_V2_NO_VALUE.get()); 197 } 198 199 authorizationID = value.stringValue(); 200 } 201 202 203 204 /** 205 * Retrieves the authorization ID string that will be used to identify the 206 * user under whose authorization the associated operation should be 207 * performed. 208 * 209 * @return The authorization ID string that will be used to identify the user 210 * under whose authorization the associated operation should be 211 * performed. 212 */ 213 @NotNull() 214 public String getAuthorizationID() 215 { 216 return authorizationID; 217 } 218 219 220 221 /** 222 * {@inheritDoc} 223 */ 224 @Override() 225 @NotNull() 226 public String getControlName() 227 { 228 return INFO_CONTROL_NAME_PROXIED_AUTHZ_V2_REQUEST.get(); 229 } 230 231 232 233 /** 234 * {@inheritDoc} 235 */ 236 @Override() 237 public void toString(@NotNull final StringBuilder buffer) 238 { 239 buffer.append("ProxiedAuthorizationV2RequestControl(authorizationID='"); 240 buffer.append(authorizationID); 241 buffer.append("')"); 242 } 243}