mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Gene Hirayama
30.05.2015 d19cd53acd39ce53a257d484725901310c23036d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ! CCPL HEADER START
  !
  ! This work is licensed under the Creative Commons
  ! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
  ! To view a copy of this license, visit
  ! http://creativecommons.org/licenses/by-nc-nd/3.0/
  ! or send a letter to Creative Commons, 444 Castro Street,
  ! Suite 900, Mountain View, California, 94041, USA.
  !
  ! You can also obtain a copy of the license at
  ! trunk/opendj3/legal-notices/CC-BY-NC-ND.txt.
  ! See the License for the specific language governing permissions
  ! and limitations under the License.
  !
  ! If applicable, add the following below this CCPL HEADER, with the fields
  ! enclosed by brackets "[]" replaced with your own identifying information:
  !      Portions Copyright [yyyy] [name of copyright owner]
  !
  ! CCPL HEADER END
  !
  !      Copyright 2011-2013 ForgeRock AS
  !    
-->
<chapter xml:id='chap-writing'
 xmlns='http://docbook.org/ns/docbook' version='5.0' xml:lang='en'
 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
 xsi:schemaLocation='http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd'
 xmlns:xlink='http://www.w3.org/1999/xlink'
 xmlns:xinclude='http://www.w3.org/2001/XInclude'>
 <title>Updating Directory Data</title>
 
 <para>Modern directory servers like OpenDJ can handle a high load of write
 requests, replicating changes quickly both on the LAN and over the WAN.</para>
 
 <para>For a complete example corresponding to the excerpts shown below, see
 <link
 xlink:href="http://opendj.forgerock.org/opendj-ldap-sdk-examples/xref/org/forgerock/opendj/examples/ShortLife.html"
 xlink:show="new">ShortLife.java</link>, one of the <link
 xlink:href="http://opendj.forgerock.org/opendj-ldap-sdk-examples/"
 xlink:show="new">OpenDJ LDAP SDK examples</link>.</para>
 
 <section xml:id="about-writes">
  <title>About Add, Modify, Rename, &amp; Delete</title>
 
  <para>The four basic CRUD operations &#8212; create, read, update, and delete
  &#8212; correspond to the LDAP operations add, search, modify (or modify DN),
  and delete.<footnote><para>The LDAP bind operation can potentially result in
  an update. Some directory servers can be configured to write time stamps in
  order to track successful or failed binds for password policy reasons.</para>
  </footnote></para>
 
  <indexterm>
   <primary>Adds</primary>
  </indexterm>
  <indexterm>
   <primary>Modifications</primary>
  </indexterm>
  <indexterm>
   <primary>Renames</primary>
  </indexterm>
  <indexterm>
   <primary>Deletes</primary>
  </indexterm>
  <indexterm>
   <primary>Authorizations</primary>
  </indexterm>
 
  <itemizedlist>
   <listitem>
    <para>An add request is used to create a new entry in an LDAP directory.
    The entry must have a unique distinguished name that belongs under a base
    DN served by the directory. The entry must have a list of attributes that
    are valid according to the directory schema.</para>
   </listitem>
 
   <listitem>
    <para>Search requests are described in the chapter on <link
    xlink:href="dev-guide#chap-reading"
    xlink:role="http://docbook.org/xlink/role/olink"><citetitle>Searching &amp;
    Comparing Directory Data</citetitle></link>.</para>
   </listitem>
 
   <listitem>
    <para>A modify request is used to add, delete, or replace attribute values
    on an entry in an LDAP directory. The resulting entry must be valid
    according to the directory schema.</para>
 
    <para>A modify DN request is used to rename or move a directory entry.
    In both cases the distinguished name changes. Renaming involves changing
    the relative distinguished name, for example from
    <literal>cn=Bob,ou=People,dc=example,dc=com</literal> to
    <literal>cn=Ted,ou=People,dc=example,dc=com</literal>. Moving
    involves changing the container where the entry is found, for example from
    <literal>cn=Barbara Jensen,ou=People,dc=Old Company,dc=com</literal> to
    <literal>cn=Barbara Jensen,ou=People,dc=New Company,dc=com</literal>.</para>
 
    <para>Although they are both considered modify DN operations, renaming a
    leaf entry is generally much simpler than moving a container entry that has
    child entries.</para>
   </listitem>
 
   <listitem>
    <para>A delete request is used to remove an entry from an LDAP
    directory.</para>
 
    <para>Directory servers can restrict deletes to leaf entries, so that you
    cannot remove an entry that has other child entries. For example, you have
    to delete <literal>uid=bjensen,ou=People,dc=example,dc=com</literal> and
    other peer entries before you delete
    <literal>ou=People,dc=example,dc=com</literal> unless you send a subtree
    delete request control.</para>
   </listitem>
  </itemizedlist>
 
  <para>As a rule, your client application must be authorized to create,
  update, and delete directory data. Therefore to prepare to change directory
  data, you first get a connection, and then bind on that connection as a
  user who is authorized to make the changes you plan to request.</para>
 </section>
 
 <section xml:id="adding-entries">
  <title>Adding Directory Entries</title>
  <indexterm>
   <primary>Adds</primary>
  </indexterm>
 
  <para>The <literal>Connection.add()</literal> methods let you provide the
  entry to add as an <literal>AddRequest</literal>, an <literal>Entry</literal>,
  or as LDIF. If the changes to make are already expressed in LDIF, then
  you can also use <literal>ChangeRecordReader</literal>s,
  <literal>ChangeRecord</literal>s, and <literal>ChangeRecordWriter</literal>s
  to handle the changes.</para>
 
  <para>The following excerpt demonstrates how to add a simple user entry under
  <literal>ou=People,dc=example,dc=com</literal>.</para>
 
  <programlisting language="java"
  >[jcp:org.forgerock.opendj.examples.ShortLife:--- JCite add ---]</programlisting>
 </section>
 
 <section xml:id="modifying-attr-values">
  <title>Modifying Directory Entry Attribute Values</title>
  <indexterm>
   <primary>Modifications</primary>
  </indexterm>
 
  <para>The <literal>Connection.modify()</literal> methods let you add, replace,
  and delete attributes values on an entry. Either the modifications are
  expressed in LDIF, or you build a <literal>ModifyRequest</literal> to
  express the changes. To build a <literal>ModifyRequest</literal>, you can
  either specify individual changes, or derive the modifications from the
  differences between the original entry and a modified copy, as in the
  following excerpt. This is not always a particularly efficient method, but
  it can be easy to use in some cases.</para>
 
  <programlisting language="java"
  >[jcp:org.forgerock.opendj.examples.ShortLife:--- JCite modify ---]</programlisting>
 
  <para>Especially when working with large entries, a more efficient choice is
  to construct a <literal>ModifyRequest</literal> without copying the entire
  entry, but instead by specifying individual changes. See a demonstration
  of this technique in <xref linkend="updating-static-groups" />.</para>
 
  <indexterm>
   <primary>Passwords</primary>
  </indexterm>
 
  <para>You can also construct a <literal>ModifyRequest</literal> for example
  to change a user password in Active Directory, as demonstrated in the
  following excerpt. When working with OpenDJ directory server, consider using
  the LDAP Password Modify extended operation instead as shown in the section,
  <link xlink:show="new" xlink:href="dev-guide#use-password-modify-extended-operation"
  xlink:role="http://docbook.org/xlink/role/olink"><citetitle>Password Modify
  Extended Operation</citetitle></link>.</para>
 
  <programlisting language="java"
  >[jcp:org.forgerock.opendj.examples.PasswordResetForAD:--- JCite main ---]</programlisting>
 
  <para>To make the modification, the example connects to Active Directory over
  LDAPS, and provides the password value in UTF-16LE format.</para>
 
  <programlisting language="java"
  >[jcp:org.forgerock.opendj.examples.PasswordResetForAD:--- JCite encodePassword ---]</programlisting>
 
  <para>If the modifications are easier to construct in LDIF, you can write the
  LDIF to the directory server as shown in the chapter, <link xlink:show="new"
  xlink:href="dev-guide#chap-ldif" xlink:role="http://docbook.org/xlink/role/olink"
  ><citetitle>Working With LDIF</citetitle></link>.</para>
 </section>
 
 <section xml:id="renaming-entries">
  <title>Renaming Directory Entries</title>
  <indexterm>
   <primary>Renames</primary>
  </indexterm>
 
  <para>The <literal>Connection.modifyDN()</literal> methods serve to rename
  entries and to move them around.</para>
 
  <para>The following excerpt demonstrates how to rename an entry.</para>
 
  <programlisting language="java"
  >[jcp:org.forgerock.opendj.examples.ShortLife:--- JCite rename ---]</programlisting>
 
  <para>If you must move rather than rename entries, have a look at the methods
  for <literal>ModifyDNRequest</literal>. You can get a new request by using
  <literal>Requests</literal> static methods.</para>
 </section>
 
 <section xml:id="deleting-entries">
  <title>Deleting Directory Entries</title>
  <indexterm>
   <primary>Deletes</primary>
  </indexterm>
 
  <para>The following excerpt demonstrates how to delete an entry with DN
  <literal>cn=Ted,ou=People,dc=example,dc=com</literal>.</para>
 
  <programlisting language="java"
  >[jcp:org.forgerock.opendj.examples.ShortLife:--- JCite delete ---]</programlisting>
 
  <para>If you must delete an entire branch of entries instead of a single
  leaf entry, build a <literal>DeleteRequest</literal> that includes the
  <literal>SubtreeDeleteRequestControl</literal>, as described in the
  section, <link xlink:href="dev-guide#use-subtree-delete-control"
  xlink:role="http://docbook.org/xlink/role/olink"><citetitle>Subtree Delete
  Request Control</citetitle></link>.</para>
 </section>
 
 <section xml:id="updating-static-groups">
  <title>Updating Static Groups</title>
  <indexterm>
   <primary>Modifications</primary>
   <secondary>Static groups</secondary>
  </indexterm>
 
  <para>Static groups enumerate user entries. Static groups can grow large.
  For an example, see the group entry at the end of <link xlink:show="new"
  xlink:href="http://opendj.forgerock.org/big-group.ldif">big-group.ldif</link>:</para>
 
  <programlisting language="ldif">dn: cn=Static,ou=Groups,dc=example,dc=com
objectClass: top
objectClass: groupofnames
cn: Static
member: uid=user.0,ou=People,dc=example,dc=com
member: uid=user.1,ou=People,dc=example,dc=com
member: uid=user.2,ou=People,dc=example,dc=com
...
member: uid=user.10000,ou=People,dc=example,dc=com</programlisting>
 
  <para>To update a static group, you either add members or remove members.
  For sample code, see <link
  xlink:href="http://opendj.forgerock.org/opendj-ldap-sdk-examples/xref/org/forgerock/opendj/examples/UpdateGroup.html"
  xlink:show="new">UpdateGroup.java</link>, one of the <link
  xlink:href="http://opendj.forgerock.org/opendj-ldap-sdk-examples/"
  xlink:show="new">OpenDJ LDAP SDK examples</link>.</para>
 
  <para>The <literal>UpdateGroup</literal> example checks that the directory
  server supports the Permissive Modify control. With directory servers such
  as OpenDJ that support the LDAP Permissive Modify control, you can use the
  control to avoid having to determine whether a given member is already in the
  group before performing the operation. Instead you can simply request an
  add or a delete modification for the member.</para>
 
  <example xml:id="update-group-with-permissive-modify"><?dbfo keep-together="auto"?>
   <title>Updating a Group With Permissive Modify</title>
   <programlisting language="java"
   >[jcp:org.forgerock.opendj.examples.UpdateGroup:--- JCite permissive ---]</programlisting>
  </example>
 
  <para>If the directory server does not support the Permissive Modify control,
  then the example checks whether the member is present in the group by using
  an LDAP compare operation. If a member to be added does not yet belong to the
  group, the example requests an add modification. If a member to be deleted
  does belong to the group, the example requests a delete modification.</para>
 
  <example xml:id="update-group-with-compare-and-modify"><?dbfo keep-together="auto"?>
   <title>Updating a Group With Compare &amp; Modify</title>
   <programlisting language="java"
   >[jcp:org.forgerock.opendj.examples.UpdateGroup:--- JCite without permissive ---]</programlisting>
 
   <para>You can change multiple member values with a single modification. The
   final argument of this form of the
   <literal>ModifyRequest.addModification()</literal> method takes a series
   of one or more values. So if you have multiple group members to add or
   delete, you can loop over your list to perform compare individual compare
   requests, then construct a single modify request to add or delete the
   group members. In other words, if you have three members to add, you can
   list the three member DNs as arguments of
   <literal>addModification</literal>.</para>
 
   <programlisting language="java"
   >String member1 = "uid=user1,ou=people,dc=example,dc=com";
String member2 = "uid=user1,ou=people,dc=example,dc=com";
String member3 = "uid=user1,ou=people,dc=example,dc=com";
final ModifyRequest addMember =
    Requests.newModifyRequest(groupDN)
        .addModification(modType, "member", member1, member2, member3);
connection.modify(addMember);</programlisting>
  </example>
 
  <para>To try the example, download and import
  <filename>big-group.ldif</filename> into your directory server, and then
  run the sample. For example, if OpenDJ is set up to with directory manager
  as <literal>cn=Directory Manager</literal>, password
  <literal>password</literal> listening on <literal>localhost</literal> port
  <literal>1389</literal>, and you run the example with arguments
  <literal>localhost 1389 cn=Static,ou=Groups,dc=example,dc=com
  uid=user.5150,ou=People,dc=example,dc=com del</literal>, the resulting output
  is <literal>The entry with DN uid=user.5150,ou=People,dc=example,dc=com has
  been deleted from the group with DN
  cn=Static,ou=Groups,dc=example,dc=com.</literal>.</para>
 </section>
</chapter>