chap-passwords.xml revision 9595176505d5e2b9c835ca24ba7f4ed010f9e061
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major<?xml version="1.0" encoding="UTF-8"?>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major<!--
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! CCPL HEADER START
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major !
a35224ef1ee8c02d389ffeeb676b4de432294fb6Phill Cunnington ! This work is licensed under the Creative Commons
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! To view a copy of this license, visit
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! http://creativecommons.org/licenses/by-nc-nd/3.0/
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! or send a letter to Creative Commons, 444 Castro Street,
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! Suite 900, Mountain View, California, 94041, USA.
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major !
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! You can also obtain a copy of the license at
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! legal/CC-BY-NC-ND.txt.
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! See the License for the specific language governing permissions
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! and limitations under the License.
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major !
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! If applicable, add the following below this CCPL HEADER, with the fields
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! enclosed by brackets "[]" replaced with your own identifying information:
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! Portions Copyright [yyyy] [name of copyright owner]
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major !
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! CCPL HEADER END
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major !
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ! Copyright 2011-2012 ForgeRock AS
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major !
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major-->
1f48f8236de7de97be1c6b9d06bef50b379c8801jenkins<chapter xml:id='chap-passwords'
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major xmlns='http://docbook.org/ns/docbook'
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major version='5.0' xml:lang='en'
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major xsi:schemaLocation='http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd'
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major xmlns:xlink='http://www.w3.org/1999/xlink'
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major xmlns:xinclude='http://www.w3.org/2001/XInclude'>
5ec701c9f8ccc403ee6fd3e41239df7dcd9faddeBruno Lavit <title>Password Management</title>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <para>OpenIDM provides password management features that help you enforce
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major password policies, limit the number of passwords users must remember, and
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major let users reset and change their passwords.</para>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <section xml:id="enforce-password-policy">
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <title>Enforcing Password Policy</title>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <para>A password policy is a set of rules defining what sequence of
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major characters constitutes an acceptable password. Acceptable passwords generally
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major are too complex for users or automated programs to generate or guess.</para>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <para>Password policies set requirements for password length, character sets
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major that passwords must contain, dictionary words and other values that passwords
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major must not contain. Password policies also require that users not reuse old
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major passwords, and that users change their passwords on a regular basis.</para>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <para>OpenIDM can enforce password policy rules by applying validation rules
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major to attributes of managed user objects. Suppose you want to rule out use of
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major the following user passwords.</para>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <itemizedlist>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <listitem><para><literal>password</literal></para></listitem>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <listitem><para><literal>123456</literal></para></listitem>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <listitem><para><literal>12345678</literal></para></listitem>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <listitem><para><literal>qwerty</literal></para></listitem>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <listitem><para><literal>abc123</literal></para></listitem>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major </itemizedlist>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <para>You could include the following configuration in
bf48db3deadd0c664202d879926139b7df9d94f1Peter Major <filename>openidm/conf/managed.json</filename> to validate passwords.</para>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
1f48f8236de7de97be1c6b9d06bef50b379c8801jenkins <programlisting language="javascript">
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major{
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "objects" : [
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major {
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "name" : "user",
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "properties" : [
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major {
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "name" : "password",
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "encryption" : {
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "key" : "openidm-sym-default"
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major }
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major }
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ],
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "onValidate" : {
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "type" : "text/javascript",
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "file" : "script/password-validator.js"
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major }
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major }
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major ]
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major}</programlisting>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <para>The corresponding script,
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <filename>openidm/script/password-validator.js</filename>, returns
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <literal>true</literal> if the password is valid. For example, the following
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major script checks that the password is not one of those listed above.</para>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <programlisting language="javascript">
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Majorconst dictionary = ['password','123456','12345678', 'qwerty', 'abc123'];
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Majorfunction isValidPassword() {
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major var cleartextObject = openidm.decrypt(object);
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major for (var i = 0; i &lt; dictionary.length; i++) {
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major if (cleartextObject.password == dictionary[i]) {
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major throw "Password Policy Violation Exception";
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major };
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major };
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major};
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter MajorisValidPassword();</programlisting>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <para>To try this script with the default example, update
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <filename>openidm/conf/managed.json</filename> as shown above, change the
a35224ef1ee8c02d389ffeeb676b4de432294fb6Phill Cunnington sample user's password in
a35224ef1ee8c02d389ffeeb676b4de432294fb6Phill Cunnington <filename>openidm/samples/sample1/data/xmlConnectorData.xml</filename> to
a35224ef1ee8c02d389ffeeb676b4de432294fb6Phill Cunnington something invalid such as <literal>123456</literal>, and add a mapping for
a35224ef1ee8c02d389ffeeb676b4de432294fb6Phill Cunnington the password property to <filename>openidm/conf/sync.json</filename>:</para>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major <programlisting>
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major"properties" : [
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major {
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "source" : "description",
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "target" : "description"
87e1cbcd02820f55e1816ee4efe9e9127be22a11James Phillpotts },
87e1cbcd02820f55e1816ee4efe9e9127be22a11James Phillpotts {
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "source" : "firstname",
a329900f13c59aa829b6b857a5e96119d249880cPhill Cunnington "target" : "givenName"
a329900f13c59aa829b6b857a5e96119d249880cPhill Cunnington },
a329900f13c59aa829b6b857a5e96119d249880cPhill Cunnington {
a329900f13c59aa829b6b857a5e96119d249880cPhill Cunnington "source" : "email",
9d652bb883e4c215dbdcab006aaf1941c3f412baRich Riley "target" : "email"
9d652bb883e4c215dbdcab006aaf1941c3f412baRich Riley },
9d652bb883e4c215dbdcab006aaf1941c3f412baRich Riley {
9d652bb883e4c215dbdcab006aaf1941c3f412baRich Riley "source" : "lastname",
9d652bb883e4c215dbdcab006aaf1941c3f412baRich Riley "target" : "familyName"
9d652bb883e4c215dbdcab006aaf1941c3f412baRich Riley },
9d652bb883e4c215dbdcab006aaf1941c3f412baRich Riley {
9d652bb883e4c215dbdcab006aaf1941c3f412baRich Riley "source" : "name",
73db2ddb960cafd7ffb6daf89eb697910d36c56dJames Phillpotts "target" : "userName"
73db2ddb960cafd7ffb6daf89eb697910d36c56dJames Phillpotts },
73db2ddb960cafd7ffb6daf89eb697910d36c56dJames Phillpotts<emphasis role="strong"> {
73db2ddb960cafd7ffb6daf89eb697910d36c56dJames Phillpotts "source" : "password",
60880aadbbac7a2c9b573e9b92dcf49d3baae87fRich Riley "target" : "password"
60880aadbbac7a2c9b573e9b92dcf49d3baae87fRich Riley },</emphasis>
60880aadbbac7a2c9b573e9b92dcf49d3baae87fRich Riley {
60880aadbbac7a2c9b573e9b92dcf49d3baae87fRich Riley "source" : "name",
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major "target" : "_id"
80ca0b9f5ad61b2335af25d4dcf25a04ebfcbc91Peter Major }
],
</programlisting>
<para>The script called for <literal>onValidate</literal> lets you define
rules to validate a property's value after OpenIDM retrieves the object,
and before storing the object. If the value violates the rules, OpenIDM
throws an exception.</para>
<para>The following excerpt from
<filename>openidm/logs/openidm0.log.0</filename> shows the exception
when trying to reconcile a user having an invalid password.</para>
<programlisting language="none">
Jan 16, 2012 10:21:11 AM
org.forgerock.openidm.sync.impl.ObjectMapping createTargetObject
WARNING: Failed to create target object
org.forgerock.openidm.objset.ForbiddenException:
Password Policy Violation Exception</programlisting>
<variablelist>
<para>The password validation mechanism can apply in many situations.</para>
<varlistentry>
<term>Password change and password reset</term>
<listitem>
<para>Password change involves changing a user or account password
in accordance with password policy. Password reset involves setting a
new user or account password on behalf of a user.</para>
<para>You can configure OpenIDM to control password values as they are
provisioned as shown in the previous examples.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Password recovery</term>
<listitem>
<para>Password recovery involves recovering a password or setting a new
password when the password has been forgotten.</para>
<para>OpenIDM can provide a self-service end user interface for password
changes, password recovery, and password reset.</para>
<!-- TODO: Show how to set up UI for this when the UI is delivered. -->
</listitem>
</varlistentry>
<varlistentry>
<term>Password comparisons with dictionary words</term>
<listitem>
<para>You can add dictionary lookups to prevent use of password values
that match dictionary words.</para>
<!-- TODO: Example -->
</listitem>
</varlistentry>
<varlistentry>
<term>Password history</term>
<listitem>
<para>You can add checks to prevent reuse of previous password
values</para>
<!-- TODO: Example -->
</listitem>
</varlistentry>
<varlistentry>
<term>Password expiration</term>
<listitem>
<para>You can configure OpenIDM to call a workflow that ensures users
are able to change expiring or to reset expired passwords.</para>
<!-- TODO: Example -->
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="password-sync">
<title>Password Synchronization</title>
<para>Password synchronization intercepts user password changes, and ensures
uniform password changes across resources that store the password. Following
password synchronization, the user authenticates using the same password on
each resource. No centralized directory or authentication server is required
for performing authentication. Password synchronization reduces the number of
passwords users need to remember, so they can use fewer, stronger
passwords.</para>
<para>OpenIDM can propagate passwords to the resources storing a user's
password. OpenIDM can intercept and synchronize passwords changed natively
on OpenDJ and Active Directory. See the example in
<filename>samples/misc/managed.json</filename> where you installed OpenIDM
for a sample password synchronization configuration.</para>
<para>Before using the sample, you must set up OpenDJ and Active Directory,
and adjust the password attributes, set in the sample as
<literal>ldapPassword</literal> for OpenDJ, <literal>adPassword</literal>
for Active Directory, and <literal>password</literal> for the internal
OpenIDM password. Also, either set up password policy enforcement on OpenDJ
or Active Directory rather than OpenIDM, or ensure that all password policies
enforced are identical to prevent password updates on one resource from being
rejected by OpenIDM or by another resource.</para>
<para>Also set up password synchronization plugins for OpenDJ and for Active
Directory. The password synchronization plugins help by intercepting password
changes on the resource before the passwords are stored in encrypted
form. The plugins then send intercepted password values to OpenIDM over an
encrypted channel.</para>
<procedure xml:id="install-opendj-password-sync-plugin">
<title>To Install the OpenDJ Password Synchronization Plugin</title>
<para>Before you start, make sure you configure OpenDJ to communicate over
LDAPS as described in the OpenDJ documentation.</para>
<para>The following steps install the plugin in OpenDJ directory server
running on the same host as OpenIDM. If you run OpenDJ on a different host
use the fully qualified domain name rather than <literal>localhost</literal>,
and use your certificates rather than the example.</para>
<step>
<para>Import the self-signed OpenIDM certificate into the trust store for
OpenDJ.</para>
<screen>$ cd /path/to/OpenDJ/config
$ keytool
-import
-alias openidm-localhost
-keystore truststore
-storepass `cat keystore.pin`
-file /path/to/openidm/samples/security/openidm-localhost-cert.txt
Owner: CN=localhost, O=OpenIDM Self-Signed Certificate
Issuer: CN=localhost, O=OpenIDM Self-Signed Certificate
Serial number: 4e4bc38e
Valid from: Wed Aug 17 15:35:10 CEST 2011 until: Tue Aug 17 15:35:10 CEST 2021
Certificate fingerprints:
MD5: B8:B3:B4:4C:F3:22:89:19:C6:55:98:C5:DF:47:DF:06
SHA1: DB:BB:F1:14:55:A0:53:80:9D:62:E7:39:FB:83:15:DA:60:63:79:D1
Signature algorithm name: SHA1withRSA
Version: 3
Trust this certificate? [no]: yes
Certificate was added to keystore</screen>
</step>
<step>
<para>Download the OpenDJ password synchronization plugin, OpenIDM Agents
- OpenDJ <?eval ${opendjPasswordPluginVersion}?>, from the OpenIDM
<link xlink:href="http://www.forgerock.org/openidm.html"
xlink:show="new">download page</link>.</para>
</step>
<step>
<para>Unzip the module delivery.</para>
<screen>$ unzip ~/Downloads/opendj-accountchange-handler-<?eval ${opendjPasswordPluginVersion}?>-SNAPSHOT.zip
creating: opendj/
creating: opendj/config/
creating: opendj/config/schema/
...</screen>
</step>
<step>
<para>Copy files to the directory where OpenDJ is installed.</para>
<screen>$ cd opendj
$ cp -r * /path/to/OpenDJ/</screen>
</step>
<step>
<para>Restart OpenDJ to load the additional schema from the module.</para>
<screen>$ cd /path/to/OpenDJ/bin
$ /stop-ds --restart</screen>
</step>
<step>
<para>Add the configuration provided to OpenDJ's configuration.</para>
<!-- TODO: Figure out how to do this with dsconfig instead of ldapmodify. -->
<screen>$ /ldapmodify
--port 1389
--hostname `hostname`
--bindDN "cn=Directory Manager"
--bindPassword "password"
--defaultAdd
--filename /config/openidm-pwsync-plugin-config.ldif
Processing ADD request for cn=OpenIDM Notification Handler,
cn=Account Status Notification Handlers,cn=config
ADD operation successful for DN cn=OpenIDM Notification Handler
,cn=Account Status Notification Handlers,cn=config</screen>
</step>
<step>
<para>Restart OpenDJ.</para>
<screen>$ /stop-ds --restart
...
[16/Jan/2012:15:55:47 +0100] category=EXTENSIONS severity=INFORMATION
msgID=1049147 msg=Loaded extension from file '/path/to/OpenDJ/lib/extensions
/opendj-accountchange-handler-<?eval ${opendjPasswordPluginVersion}?>.jar' (build &lt;unknown&gt;,
revision &lt;unknown&gt;)
...
[16/Jan/2012:15:55:51 +0100] category=CORE severity=NOTICE msgID=458891 msg=The
Directory Server has sent an alert notification generated by class
org.opends.server.core.DirectoryServer (alert type
org.opends.server.DirectoryServerStarted, alert ID 458887):
The Directory Server has started successfully</screen>
</step>
<step>
<para>Enable the plugin for the appropriate password policy.</para>
<para>The following command enables the plugin for the default password
policy.</para>
<screen>$ /dsconfig
set-password-policy-prop
--port 4444
--hostname `hostname`
--bindDN "cn=Directory Manager"
--bindPassword password
--policy-name "Default Password Policy"
--set account-status-notification-handler:"OpenIDM Notification Handler"
--trustStorePath /config/admin-truststore
--no-prompt</screen>
</step>
</procedure>
<procedure xml:id="install-ad-password-sync-plugin">
<title>To Install the Active Directory Password Synchronization Plugin</title>
<para>You install the plugin on Active Directory primary domain controllers
to intercept password changes, and send the password values to OpenIDM over
an encrypted channel. You must have Administrator privileges to install the
plugin.</para>
<step>
<para>Download the Active Directory password synchronization plugin,
OpenIDM Agents - AD <?eval ${adPasswordPluginVersion}?>, from the OpenIDM
<link xlink:href="http://www.forgerock.org/openidm.html"
xlink:show="new">download page</link>.</para>
</step>
<step>
<para>Unzip the plugin, and double-click <filename>setup.exe</filename> to
launch the installation wizard.</para>
</step>
<step>
<para>Complete the installation with the help of the following hints.</para>
<variablelist>
<varlistentry>
<!-- Yes, this hint seems unnecessary. But if people need to know what
licensing is used without opening up the installer, they can get
that info right here: -->
<term>CDDL license agreement</term>
<listitem>
<para>You must accept the agreement to proceed with the
installation.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>OpenIDM URL</term>
<listitem>
<para>URL where OpenIDM is deployed such as
<literal>https://openidm.example.com:8444/openidm</literal> for
SSL mutual authentication</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Private Key alias</term>
<listitem>
<para>Alias used for the OpenIDM certificate also stored in the
<filename>keystore.jceks</filename> file, such as
<literal>openidm-localhost</literal> used for evaluation</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Private Key password</term>
<listitem>
<para>Password to access the PFX keystore file, such as
<literal>changeit</literal> for evaluation. PFX files contain
encrypted private keys, certificates used for authentication and
encryption.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Directory poll interval (seconds)</term>
<listitem>
<para>Number of seconds between calls to check that Active Directory
is available, such as 60</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Query ID parameter</term>
<listitem>
<para>Query identifier configured in OpenIDM the
<filename>openidm/conf/repo.*.json</filename> file. Use
<literal>for-userName</literal> for evaluation.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>OpenIDM user password attribute </term>
<listitem>
<para>Password attribute for the <literal>managed/user</literal> object
to which OpenIDM applies password changes</para>
</listitem>
</varlistentry>
<varlistentry>
<term>OpenIDM user search attribute</term>
<listitem>
<para>The <literal>sAMAccountName</literal> value holder attribute name
in the query definition. For example,
<literal>"SELECT * FROM ${_resource} WHERE userName = '${uid}'"</literal>.
Use <literal>uid</literal> for the evaluation.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Select Certificate File</term>
<listitem>
<para>The PKCS 12 format PFX file containing the certificate used to
encrypt communications with OpenIDM. Use
<filename>openidm/samples/security/openidm-localhost.p12</filename> for
evaluation.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Select Output Directory</term>
<listitem>
<para>Select a secure directory where the password changes are queued.
The queue contains the encrypted passwords. Yet, the server has to
prevent access to this folder except access by the <literal>Password
Sync service</literal>. The path name cannot include spaces.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Select Log Directory</term>
<listitem>
<para>The plugin stores logs in the location you select. The path name
cannot include spaces.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Select Destination Location</term>
<listitem>
<para>Setup installs the plugin in the location you select, by default
<filename>C:\Program Files\OpenIDM Password Sync</filename>.</para>
</listitem>
</varlistentry>
</variablelist>
</step>
<step>
<para>After running the installation wizard, restart the computer.</para>
</step>
<step>
<para>If you must change any settings after installation, access settings
using the Registry Editor under HKEY_LOCAL_MACHINE &gt; SOFTWARE &gt;
ForgeRock &gt; OpenIDM &gt; PasswordSync.</para>
</step>
</procedure>
<procedure xml:id="setup-openidm-for-password-sync">
<title>To Set Up OpenIDM to Handle Password Changes</title>
<para>Follow these steps to configure OpenIDM to access password changes
from the directory server.</para>
<step>
<para>Add the directory server certificate to the OpenIDM trust store so
that OpenIDM knows to trust the directory server during mutual
authentication.</para>
<para>The following commands show how to do this with the default OpenDJ
and OpenIDM settings.</para>
<screen>$ cd /path/to/OpenDJ/config/
$ keytool
-keystore keystore
-storepass `cat keystore.pin`
-export
-alias server-cert
&gt; /tmp/opendj.crt
$ cd /path/to/openidm/security/
$ keytool
-import
-alias opendj-server-cert
-file /tmp/opendj.crt
-keystore truststore
-storepass changeit
-trustcacerts
Owner: CN=localhost.localdomain, O=OpenDJ Self-Signed Certificate
Issuer: CN=localhost.localdomain, O=OpenDJ Self-Signed Certificate
Serial number: 4f143976
Valid from: Mon Jan 16 15:51:34 CET 2012 until: Wed Jan 15 15:51:34 CET 2014
Certificate fingerprints:
MD5: 7B:7A:75:FC:5A:F0:65:E5:84:43:6D:10:B9:EA:CC:F0
SHA1: D1:C6:C9:8A:EA:09:FD:1E:48:BB:B2:F5:95:41:50:2C:AB:4D:0F:C9
Signature algorithm name: SHA1withRSA
Version: 3
Trust this certificate? [no]: yes
Certificate was added to keystore</screen>
</step>
<step>
<para>Add the configuration to managed objects to handle password
synchronization.</para>
<para>You can find an example for synchronization with both OpenDJ and
Active Directory in <filename>samples/misc/managed.json</filename>,
JavaScript lines folded for readability:</para>
<programlisting language="javascript">
{
"objects": [
{
"name": "user",
"properties": [
{
"name": "ldapPassword",
"encryption": {
"key": "openidm-sym-default"
}
},
{
"name": "adPassword",
"encryption": {
"key": "openidm-sym-default"
}
},
{
"name": "password",
"encryption": {
"key": "openidm-sym-default"
}
}
],
"onUpdate": {
"type": "text/javascript",
"source":
"if (newObject.ldapPassword != oldObject.ldapPassword) {
newObject.password = newObject.ldapPassword
} else if (newObject.adPassword != oldObject.adPassword) {
newObject.password = newObject.adPassword
}"
}
}
]
}</programlisting>
<para>This sample assumes you define the password as
<literal>ldapPassword</literal> for OpenDJ, and
<literal>adPassword</literal> for Active Directory.</para>
</step>
<step>
<para>When you change a password on the directory server and run
reconciliation, you notice the value changes in OpenIDM.</para>
<screen>$ tail -f openidm/audit/activity.csv | grep bjensen
...userName=bjensen, ... password={$crypto={...data=tEsy7ZXo6nZtEqzW/uVE/A==...
...userName=bjensen, ... password={$crypto={...data=BReT79lnQEPcvfQG3ibLpg==...</screen>
</step>
</procedure>
</section>
</chapter>