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.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 DN
071     * "uid=john.doe,ou=People,dc=example,dc=com":
072     * <PRE>
073     *   DeleteRequest deleteRequest =
074     *        new DeleteRequest("cn=no longer needed,dc=example,dc=com");
075     *   deleteRequest.addControl(new ProxiedAuthorizationV2RequestControl(
076     *        "dn:uid=john.doe,ou=People,dc=example,dc=com"));
077     *
078     *   try
079     *   {
080     *     LDAPResult deleteResult = connection.delete(deleteRequest);
081     *     // If we got here, then the delete was successful.
082     *   }
083     *   catch (LDAPException le)
084     *   {
085     *     if (le.getResultCode() == ResultCode.AUTHORIZATION_DENIED)
086     *     {
087     *       // The delete failed because the authenticated user does not have
088     *       // permission to use the proxied authorization V2 control.
089     *     }
090     *     else
091     *     {
092     *       // The delete failed for some other reason.
093     *     }
094     *   }
095     * </PRE>
096     */
097    @NotMutable()
098    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
099    public final class ProxiedAuthorizationV2RequestControl
100           extends Control
101    {
102      /**
103       * The OID (2.16.840.1.113730.3.4.18) for the proxied authorization v2 request
104       * control.
105       */
106      public static final String PROXIED_AUTHORIZATION_V2_REQUEST_OID =
107           "2.16.840.1.113730.3.4.18";
108    
109    
110    
111      /**
112       * The serial version UID for this serializable class.
113       */
114      private static final long serialVersionUID = 1054244283964851067L;
115    
116    
117    
118      // The authorization ID string that may be used to identify the user under
119      // whose authorization the associated operation should be performed.
120      private final String authorizationID;
121    
122    
123    
124      /**
125       * Creates a new proxied authorization V2 request control that will proxy as
126       * the specified user.
127       *
128       * @param  authorizationID  The authorization ID string that will be used to
129       *                          identify the user under whose authorization the
130       *                          associated operation should be performed.  It may
131       *                          take one of three forms:  it can be an empty
132       *                          string (to indicate that the operation should use
133       *                          anonymous authorization), a string that begins
134       *                          with "dn:" and is followed by the DN of the target
135       *                          user, or a string that begins with "u:" and is
136       *                          followed by the username for the target user
137       *                          (where the process of mapping the provided
138       *                          username to the corresponding entry will depend on
139       *                          the server configuration).  It must not be
140       *                          {@code null}.
141       */
142      public ProxiedAuthorizationV2RequestControl(final String authorizationID)
143      {
144        super(PROXIED_AUTHORIZATION_V2_REQUEST_OID, true,
145              new ASN1OctetString(authorizationID));
146    
147        ensureNotNull(authorizationID);
148    
149        this.authorizationID = authorizationID;
150      }
151    
152    
153    
154      /**
155       * Creates a new proxied authorization v2 request control which is decoded
156       * from the provided generic control.
157       *
158       * @param  control  The generic control to be decoded as a proxied
159       *                  authorization v2 request control.
160       *
161       * @throws  LDAPException  If the provided control cannot be decoded as a
162       *                         proxied authorization v2 request control.
163       */
164      public ProxiedAuthorizationV2RequestControl(final Control control)
165             throws LDAPException
166      {
167        super(control);
168    
169        final ASN1OctetString value = control.getValue();
170        if (value == null)
171        {
172          throw new LDAPException(ResultCode.DECODING_ERROR,
173                                  ERR_PROXY_V2_NO_VALUE.get());
174        }
175    
176        authorizationID = value.stringValue();
177      }
178    
179    
180    
181      /**
182       * Retrieves the authorization ID string that will be used to identify the
183       * user under whose authorization the associated operation should be
184       * performed.
185       *
186       * @return  The authorization ID string that will be used to identify the user
187       *          under whose authorization the associated operation should be
188       *          performed.
189       */
190      public String getAuthorizationID()
191      {
192        return authorizationID;
193      }
194    
195    
196    
197      /**
198       * {@inheritDoc}
199       */
200      @Override()
201      public String getControlName()
202      {
203        return INFO_CONTROL_NAME_PROXIED_AUTHZ_V2_REQUEST.get();
204      }
205    
206    
207    
208      /**
209       * {@inheritDoc}
210       */
211      @Override()
212      public void toString(final StringBuilder buffer)
213      {
214        buffer.append("ProxiedAuthorizationV2RequestControl(authorizationID='");
215        buffer.append(authorizationID);
216        buffer.append("')");
217      }
218    }