001 /*
002 * Copyright 2007-2013 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2013 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.ldap.sdk.controls;
022
023
024
025 import com.unboundid.asn1.ASN1Element;
026 import com.unboundid.asn1.ASN1OctetString;
027 import com.unboundid.asn1.ASN1Sequence;
028 import com.unboundid.ldap.sdk.Control;
029 import com.unboundid.ldap.sdk.DN;
030 import com.unboundid.ldap.sdk.LDAPException;
031 import com.unboundid.ldap.sdk.ResultCode;
032 import com.unboundid.util.NotMutable;
033 import com.unboundid.util.ThreadSafety;
034 import com.unboundid.util.ThreadSafetyLevel;
035
036 import static com.unboundid.ldap.sdk.controls.ControlMessages.*;
037 import static com.unboundid.util.Debug.*;
038 import static com.unboundid.util.Validator.*;
039
040
041
042 /**
043 * This class provides an implementation of the proxied authorization V1
044 * request control, which may be used to request that the associated operation
045 * be performed as if it had been requested by some other user. It is based on
046 * the specification provided in early versions of the
047 * draft-weltman-ldapv3-proxy Internet Draft (this implementation is based on
048 * the "-04" revision). Later versions of the draft, and subsequently
049 * <A HREF="http://www.ietf.org/rfc/rfc4370.txt">RFC 4370</A>, define a second
050 * version of the proxied authorization control with a different OID and
051 * different value format. This control is supported primarily for legacy
052 * purposes, and it is recommended that new applications use the
053 * {@link ProxiedAuthorizationV2RequestControl} instead if this version.
054 * <BR><BR>
055 * The value of this control includes the DN of the user as whom the operation
056 * should be performed. Note that it should be a distinguished name, and not an
057 * authzId value as is used in the proxied authorization V2 control.
058 * <BR><BR>
059 * This control may be used in conjunction with add, delete, compare, delete,
060 * extended, modify, modify DN, and search requests. In that case, the
061 * associated operation will be processed under the authority of the specified
062 * authorization identity rather than the identity associated with the client
063 * connection (i.e., the user as whom that connection is bound). Note that
064 * because of the inherent security risks associated with the use of the proxied
065 * authorization control, most directory servers which support its use enforce
066 * strict restrictions on the users that are allowed to request this control.
067 * Note that while the directory server should return a
068 * {@link ResultCode#AUTHORIZATION_DENIED} result for a proxied authorization V2
069 * control if the requester does not have the appropriate permission to use that
070 * control, this result will not necessarily be used for the same condition with
071 * the proxied authorization V1 control because this result code was not defined
072 * until the release of the proxied authorization V2 specification.
073 * code.
074 * <BR><BR>
075 * There is no corresponding response control for this request control.
076 * <BR><BR>
077 * <H2>Example</H2>
078 * The following example demonstrates the use of the proxied authorization V1
079 * control to delete an entry under the authority of the user with DN
080 * "uid=john.doe,ou=People,dc=example,dc=com":
081 * <PRE>
082 * DeleteRequest deleteRequest =
083 * new DeleteRequest("cn=no longer needed,dc=example,dc=com");
084 * deleteRequest.addControl(new ProxiedAuthorizationV1RequestControl(
085 * "uid=john.doe,ou=People,dc=example,dc=com"));
086 *
087 * try
088 * {
089 * LDAPResult deleteResult = connection.delete(deleteRequest);
090 * // If we got here, then the delete was successful.
091 * }
092 * catch (LDAPException le)
093 * {
094 * // The delete failed for some reason. It may or may not have been
095 * // because the authenticated user does not have permission to use the
096 * // proxied authorization V1 control.
097 * }
098 * </PRE>
099 */
100 @NotMutable()
101 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
102 public final class ProxiedAuthorizationV1RequestControl
103 extends Control
104 {
105 /**
106 * The OID (2.16.840.1.113730.3.4.12) for the proxied authorization v1 request
107 * control.
108 */
109 public static final String PROXIED_AUTHORIZATION_V1_REQUEST_OID =
110 "2.16.840.1.113730.3.4.12";
111
112
113
114 /**
115 * The serial version UID for this serializable class.
116 */
117 private static final long serialVersionUID = 7312632337431962774L;
118
119
120
121 // The DN of the target user under whose authorization the associated
122 // operation should be performed.
123 private final String proxyDN;
124
125
126
127 /**
128 * Creates a new proxied authorization V1 request control that will proxy as
129 * the specified user.
130 *
131 * @param proxyDN The DN of the target user under whose authorization the
132 * associated request should be performed. It must not be
133 * {@code null}, although it may be an empty string to
134 * request an anonymous authorization.
135 */
136 public ProxiedAuthorizationV1RequestControl(final String proxyDN)
137 {
138 super(PROXIED_AUTHORIZATION_V1_REQUEST_OID, true, encodeValue(proxyDN));
139
140 ensureNotNull(proxyDN);
141
142 this.proxyDN = proxyDN;
143 }
144
145
146
147 /**
148 * Creates a new proxied authorization V1 request control that will proxy as
149 * the specified user.
150 *
151 * @param proxyDN The DN of the target user under whose authorization the
152 * associated request should be performed. It must not be
153 * {@code null}.
154 */
155 public ProxiedAuthorizationV1RequestControl(final DN proxyDN)
156 {
157 super(PROXIED_AUTHORIZATION_V1_REQUEST_OID, true,
158 encodeValue(proxyDN.toString()));
159
160 this.proxyDN = proxyDN.toString();
161 }
162
163
164
165 /**
166 * Creates a new proxied authorization v1 request control which is decoded
167 * from the provided generic control.
168 *
169 * @param control The generic control to be decoded as a proxied
170 * authorization v1 request control.
171 *
172 * @throws LDAPException If the provided control cannot be decoded as a
173 * proxied authorization v1 request control.
174 */
175 public ProxiedAuthorizationV1RequestControl(final Control control)
176 throws LDAPException
177 {
178 super(control);
179
180 final ASN1OctetString value = control.getValue();
181 if (value == null)
182 {
183 throw new LDAPException(ResultCode.DECODING_ERROR,
184 ERR_PROXY_V1_NO_VALUE.get());
185 }
186
187 try
188 {
189 final ASN1Element valueElement = ASN1Element.decode(value.getValue());
190 final ASN1Element[] elements =
191 ASN1Sequence.decodeAsSequence(valueElement).elements();
192 proxyDN = ASN1OctetString.decodeAsOctetString(elements[0]).stringValue();
193 }
194 catch (Exception e)
195 {
196 debugException(e);
197 throw new LDAPException(ResultCode.DECODING_ERROR,
198 ERR_PROXYV1_DECODE_ERROR.get(e), e);
199 }
200 }
201
202
203
204 /**
205 * Encodes the provided information into an octet string that can be used as
206 * the value for this control.
207 *
208 * @param proxyDN The DN of the target user under whose authorization the
209 * associated request should be performed. It must not be
210 * {@code null}, although it may be an empty string to
211 * request an anonymous authorization.
212 *
213 * @return An ASN.1 octet string that can be used as the value for this
214 * control.
215 */
216 private static ASN1OctetString encodeValue(final String proxyDN)
217 {
218 final ASN1Element[] valueElements =
219 {
220 new ASN1OctetString(proxyDN)
221 };
222
223 return new ASN1OctetString(new ASN1Sequence(valueElements).encode());
224 }
225
226
227
228 /**
229 * Retrieves the DN of the target user under whose authorization the
230 * associated request should be performed.
231 *
232 * @return The DN of the target user under whose authorization the associated
233 * request should be performed.
234 */
235 public String getProxyDN()
236 {
237 return proxyDN;
238 }
239
240
241
242 /**
243 * {@inheritDoc}
244 */
245 @Override()
246 public String getControlName()
247 {
248 return INFO_CONTROL_NAME_PROXIED_AUTHZ_V1_REQUEST.get();
249 }
250
251
252
253 /**
254 * {@inheritDoc}
255 */
256 @Override()
257 public void toString(final StringBuilder buffer)
258 {
259 buffer.append("ProxiedAuthorizationV1RequestControl(proxyDN='");
260 buffer.append(proxyDN);
261 buffer.append("')");
262 }
263 }