001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2012-2014 ForgeRock AS.
015 */
016
017package org.forgerock.opendj.examples;
018
019import java.util.Collection;
020
021import org.forgerock.opendj.ldap.Connection;
022import org.forgerock.opendj.ldap.LdapException;
023import org.forgerock.opendj.ldap.LDAPConnectionFactory;
024import org.forgerock.opendj.ldap.RootDSE;
025import org.forgerock.opendj.ldap.requests.PasswordModifyExtendedRequest;
026import org.forgerock.opendj.ldap.requests.Requests;
027import org.forgerock.opendj.ldap.requests.WhoAmIExtendedRequest;
028import org.forgerock.opendj.ldap.responses.PasswordModifyExtendedResult;
029import org.forgerock.opendj.ldap.responses.Result;
030import org.forgerock.opendj.ldap.responses.WhoAmIExtendedResult;
031
032/**
033 * This command-line client demonstrates use of LDAP extended operations. The
034 * client takes as arguments the host and port for the directory server, and
035 * expects to find the entries and access control instructions as defined in <a
036 * href="http://opendj.forgerock.org/Example.ldif">Example.ldif</a>.
037 *
038 * This client connects as <code>cn=Directory Manager</code> with password
039 * <code>password</code>. Not a best practice; in real code use application
040 * specific credentials to connect, and ensure that your application has access
041 * to use the LDAP extended operations needed.
042 */
043public final class ExtendedOperations {
044
045    /**
046     * Connect to the server, and then try to use some LDAP extended operations.
047     *
048     * @param args
049     *            The command line arguments: host, port
050     */
051    public static void main(final String[] args) {
052        if (args.length != 2) {
053            System.err.println("Usage: host port");
054            System.err.println("For example: localhost 1389");
055            System.exit(1);
056        }
057        final String host = args[0];
058        final int port = Integer.parseInt(args[1]);
059
060        final LDAPConnectionFactory factory = new LDAPConnectionFactory(host, port);
061        Connection connection = null;
062
063        try {
064            connection = factory.getConnection();
065            checkSupportedExtendedOperations(connection);
066
067            final String user = "cn=Directory Manager";
068            final char[] password = "password".toCharArray();
069            connection.bind(user, password);
070
071            // Uncomment a method to run one of the examples.
072
073            // For a Cancel Extended request, see the SearchAsync example.
074            //usePasswordModifyExtendedRequest(connection);
075            // For StartTLS, see the authentication examples.
076            useWhoAmIExtendedRequest(connection);
077
078        } catch (LdapException e) {
079            System.err.println(e.getMessage());
080            System.exit(e.getResult().getResultCode().intValue());
081            return;
082        } finally {
083            if (connection != null) {
084                connection.close();
085            }
086        }
087    }
088
089    /**
090     * Use the password modify extended request.
091     *
092     * @param connection
093     *            Active connection to LDAP server containing <a
094     *            href="http://opendj.forgerock.org/Example.ldif"
095     *            >Example.ldif</a> content.
096     * @throws LdapException
097     *             Operation failed.
098     */
099    static void usePasswordModifyExtendedRequest(Connection connection) throws LdapException {
100        // --- JCite password modify ---
101        if (isSupported(PasswordModifyExtendedRequest.OID)) {
102            final String userIdentity = "u:scarter";
103            final char[] oldPassword = "sprain".toCharArray();
104            final char[] newPassword = "secret12".toCharArray();
105
106            final PasswordModifyExtendedRequest request =
107                    Requests.newPasswordModifyExtendedRequest()
108                        .setUserIdentity(userIdentity)
109                        .setOldPassword(oldPassword)
110                        .setNewPassword(newPassword);
111
112            final PasswordModifyExtendedResult result =
113                    connection.extendedRequest(request);
114            if (result.isSuccess()) {
115                System.out.println("Changed password for " + userIdentity);
116            } else {
117                System.err.println(result.getDiagnosticMessage());
118            }
119        } else {
120            System.err.println("PasswordModifyExtendedRequest not supported");
121        }
122        // --- JCite password modify ---
123    }
124
125    /**
126     * Use the Who Am I? extended request.
127     *
128     * @param connection Active connection to LDAP server containing <a
129     *            href="http://opendj.forgerock.org/Example.ldif"
130     *            >Example.ldif</a> content.
131     * @throws LdapException
132     *             Operation failed.
133     */
134    static void useWhoAmIExtendedRequest(Connection connection) throws LdapException {
135        // --- JCite who am I ---
136        if (isSupported(WhoAmIExtendedRequest.OID)) {
137
138            final String name = "uid=bjensen,ou=People,dc=example,dc=com";
139            final char[] password = "hifalutin".toCharArray();
140
141            final Result result = connection.bind(name, password);
142            if (result.isSuccess()) {
143
144                final WhoAmIExtendedRequest request =
145                        Requests.newWhoAmIExtendedRequest();
146                final WhoAmIExtendedResult extResult =
147                        connection.extendedRequest(request);
148
149                if (extResult.isSuccess()) {
150                    System.out.println("Authz ID: "  + extResult.getAuthorizationID());
151                }
152            }
153        } else {
154            System.err.println("WhoAmIExtendedRequest not supported");
155        }
156        // --- JCite who am I ---
157    }
158
159    // --- JCite check support ---
160    /**
161     * Controls supported by the LDAP server.
162     */
163    private static Collection<String> extendedOperations;
164
165    /**
166     * Populate the list of supported LDAP extended operation OIDs.
167     *
168     * @param connection
169     *            Active connection to the LDAP server.
170     * @throws LdapException
171     *             Failed to get list of extended operations.
172     */
173    static void checkSupportedExtendedOperations(Connection connection) throws LdapException {
174        extendedOperations = RootDSE.readRootDSE(connection)
175                .getSupportedExtendedOperations();
176    }
177
178    /**
179     * Check whether an extended operation is supported. Call
180     * {@code checkSupportedExtendedOperations} first.
181     *
182     * @param extendedOperation
183     *            Check support for this extended operation, provided by OID.
184     * @return True if the control is supported.
185     */
186    static boolean isSupported(final String extendedOperation) {
187        return extendedOperations != null && extendedOperations.contains(extendedOperation);
188    }
189    // --- JCite check support ---
190
191    /**
192     * Constructor not used.
193     */
194    private ExtendedOperations() {
195        // Not used.
196    }
197}