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