activeldap 5.2.4 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/active_ldap.rb CHANGED
@@ -1,4 +1,3 @@
1
- require "rubygems"
2
1
  require "active_model"
3
2
  require "active_support/core_ext"
4
3
 
@@ -1,6 +1,6 @@
1
1
  # Your LDAP server needs to accept 'phonetic' attribute option for test.
2
2
  # This is a LDIF file for OpenLDAP to do the configuration.
3
- # You can use this file by the following command linne on Debian GNU/Linux
3
+ # You can use this file by the following command line on Debian GNU/Linux
4
4
  # or Ubuntu:
5
5
  # % sudo -H ldapmodify -Y EXTERNAL -H ldapi:/// -f test/add-phonetic-attribute-options-to-slapd.ldif
6
6
  version: 1
@@ -23,6 +23,7 @@ module AlTestUtils
23
23
  include TemporaryEntry
24
24
  include CommandSupport
25
25
  include MockLogger
26
+ include Omittable
26
27
  end
27
28
  end
28
29
 
@@ -39,7 +40,13 @@ module AlTestUtils
39
40
  @top_dir = File.expand_path(File.join(@base_dir, ".."))
40
41
  @example_dir = File.join(@top_dir, "examples")
41
42
  @fixtures_dir = File.join(@base_dir, "fixtures")
42
- @config_file = File.join(@base_dir, "config.yaml")
43
+ current_config_file = File.expand_path("config.yaml")
44
+ test_config_file = File.join(@base_dir, "config.yaml")
45
+ if File.exist?(current_config_file)
46
+ @config_file = current_config_file
47
+ else
48
+ @config_file = test_config_file
49
+ end
43
50
  ActiveLdap::Base.configurations = read_config
44
51
  end
45
52
 
@@ -175,6 +182,7 @@ module AlTestUtils
175
182
  populate_ou
176
183
  populate_user_class
177
184
  populate_group_class
185
+ populate_group_of_urls_class
178
186
  populate_associations
179
187
  end
180
188
 
@@ -208,7 +216,7 @@ module AlTestUtils
208
216
  end
209
217
 
210
218
  def populate_ou
211
- %w(Users Groups).each do |name|
219
+ %w(Users Groups GroupOfURLsSet).each do |name|
212
220
  make_ou(name)
213
221
  end
214
222
  end
@@ -239,6 +247,14 @@ module AlTestUtils
239
247
  assign_class_name(@group_class, "Group")
240
248
  end
241
249
 
250
+ def populate_group_of_urls_class
251
+ @group_of_urls_class = Class.new(ActiveLdap::Base)
252
+ @group_of_urls_class.ldap_mapping :prefix => "ou=GroupOfURLsSet",
253
+ :scope => :sub,
254
+ :classes => ["groupOfURLs"]
255
+ assign_class_name(@group_of_urls_class, "GroupOfURLs")
256
+ end
257
+
242
258
  def populate_associations
243
259
  @user_class.belongs_to :groups, :many => "memberUid"
244
260
  @user_class.belongs_to :primary_group,
@@ -273,41 +289,70 @@ module AlTestUtils
273
289
  super
274
290
  @user_index = 0
275
291
  @group_index = 0
292
+ @group_of_urls_index = 0
293
+ @temporary_uids = []
294
+ end
295
+
296
+ def teardown
297
+ @temporary_uids.each do |uid|
298
+ delete_temporary_user(uid)
299
+ end
300
+ super
301
+ end
302
+
303
+ def delete_temporary_user(uid)
304
+ return unless @user_class.exists?(uid)
305
+ @user_class.search(:value => uid) do |dn, attribute|
306
+ @user_class.remove_connection(dn)
307
+ @user_class.delete(dn)
308
+ end
309
+ end
310
+
311
+ def build_temporary_user(config={})
312
+ uid = config[:uid] || "temp-user#{@user_index}"
313
+ password = config[:password] || "password#{@user_index}"
314
+ uid_number = config[:uid_number] || default_uid
315
+ gid_number = config[:gid_number] || default_gid
316
+ home_directory = config[:home_directory] || "/nonexistent"
317
+ see_also = config[:see_also]
318
+ user = nil
319
+ _wrap_assertion do
320
+ assert(!@user_class.exists?(uid))
321
+ assert_raise(ActiveLdap::EntryNotFound) do
322
+ @user_class.find(uid).dn
323
+ end
324
+ user = @user_class.new(uid)
325
+ assert(user.new_entry?)
326
+ user.cn = user.uid
327
+ user.sn = user.uid
328
+ user.uid_number = uid_number
329
+ user.gid_number = gid_number
330
+ user.home_directory = home_directory
331
+ user.user_password = ActiveLdap::UserPassword.ssha(password)
332
+ user.see_also = see_also
333
+ unless config[:simple]
334
+ user.add_class('shadowAccount', 'inetOrgPerson',
335
+ 'organizationalPerson')
336
+ user.user_certificate = certificate
337
+ user.jpeg_photo = jpeg_photo
338
+ end
339
+ user.save
340
+ assert(!user.new_entry?)
341
+ end
342
+ [@user_class.find(user.uid), password]
276
343
  end
277
344
 
278
345
  def make_temporary_user(config={})
279
346
  @user_index += 1
280
- uid = config[:uid] || "temp-user#{@user_index}"
281
- ensure_delete_user(uid) do
282
- password = config[:password] || "password#{@user_index}"
283
- uid_number = config[:uid_number] || default_uid
284
- gid_number = config[:gid_number] || default_gid
285
- home_directory = config[:home_directory] || "/nonexistent"
286
- see_also = config[:see_also]
287
- _wrap_assertion do
288
- assert(!@user_class.exists?(uid))
289
- assert_raise(ActiveLdap::EntryNotFound) do
290
- @user_class.find(uid).dn
291
- end
292
- user = @user_class.new(uid)
293
- assert(user.new_entry?)
294
- user.cn = user.uid
295
- user.sn = user.uid
296
- user.uid_number = uid_number
297
- user.gid_number = gid_number
298
- user.home_directory = home_directory
299
- user.user_password = ActiveLdap::UserPassword.ssha(password)
300
- user.see_also = see_also
301
- unless config[:simple]
302
- user.add_class('shadowAccount', 'inetOrgPerson',
303
- 'organizationalPerson')
304
- user.user_certificate = certificate
305
- user.jpeg_photo = jpeg_photo
306
- end
307
- user.save
308
- assert(!user.new_entry?)
309
- yield(@user_class.find(user.uid), password)
347
+ config = config.merge(uid: config[:uid] || "temp-user#{@user_index}")
348
+ uid = config[:uid]
349
+ @temporary_uids << uid
350
+ if block_given?
351
+ ensure_delete_user(uid) do
352
+ yield(*build_temporary_user(config))
310
353
  end
354
+ else
355
+ build_temporary_user(config)
311
356
  end
312
357
  end
313
358
 
@@ -331,15 +376,30 @@ module AlTestUtils
331
376
  end
332
377
  end
333
378
 
379
+ def make_temporary_group_of_urls(config={})
380
+ @group_of_urls_index += 1
381
+ cn = config[:cn] || "temp-group-of-urls-#{@group_of_urls_index}"
382
+ ensure_delete_group_of_urls(cn) do
383
+ _wrap_assertion do
384
+ assert(!@group_of_urls_class.exists?(cn))
385
+ assert_raise(ActiveLdap::EntryNotFound) do
386
+ @group_of_urls_class.find(cn)
387
+ end
388
+ group_of_urls = @group_of_urls_class.new(cn)
389
+ assert(group_of_urls.new_entry?)
390
+ group_of_urls.member_url = config[:member_url]
391
+ assert(group_of_urls.save!)
392
+ assert(!group_of_urls.new_entry?)
393
+ yield(@group_of_urls_class.find(group_of_urls.cn))
394
+ end
395
+ end
396
+ end
397
+
334
398
  def ensure_delete_user(uid)
335
399
  yield(uid)
336
400
  ensure
337
- if @user_class.exists?(uid)
338
- @user_class.search(:value => uid) do |dn, attribute|
339
- @user_class.remove_connection(dn)
340
- @user_class.delete(dn)
341
- end
342
- end
401
+ delete_temporary_user(uid)
402
+ @temporary_uids.delete(uid)
343
403
  end
344
404
 
345
405
  def ensure_delete_group(cn)
@@ -348,6 +408,12 @@ module AlTestUtils
348
408
  @group_class.delete(cn) if @group_class.exists?(cn)
349
409
  end
350
410
 
411
+ def ensure_delete_group_of_urls(cn)
412
+ yield(cn)
413
+ ensure
414
+ @group_of_urls_class.delete(cn) if @group_of_urls_class.exists?(cn)
415
+ end
416
+
351
417
  def default_uid
352
418
  "10000#{@user_index}"
353
419
  end
@@ -373,6 +439,10 @@ module AlTestUtils
373
439
  end
374
440
 
375
441
  def run_command(*args, &block)
442
+ if RUBY_VERSION >= "2.7"
443
+ omit("Need to fix an optional arguments warning in net-ldap: " +
444
+ "ruby-ldap/ruby-net-ldap/pull/342")
445
+ end
376
446
  file = Tempfile.new("al-command-support")
377
447
  file.open
378
448
  file.puts(ActiveLdap::Base.configurations["test"].to_yaml)
@@ -425,4 +495,21 @@ module AlTestUtils
425
495
  ActiveLdap::Base.logger = original_logger
426
496
  end
427
497
  end
498
+
499
+ module Omittable
500
+ def omit_if_jruby(message=nil)
501
+ return unless RUBY_PLATFORM == "java"
502
+ omit(message || "This test is not for JRuby")
503
+ end
504
+
505
+ def omit_unless_jruby(message=nil)
506
+ return if RUBY_PLATFORM == "java"
507
+ omit(message || "This test is only for JRuby")
508
+ end
509
+
510
+ def omit_if_ldap(message=nil)
511
+ return if current_configuration[:adapter] == "ldap"
512
+ omit(message || "This test is not for ruby-ldap")
513
+ end
514
+ end
428
515
  end
@@ -0,0 +1,22 @@
1
+ # Your LDAP server needs to support dynamic list for test.
2
+ # This is a LDIF file for OpenLDAP to do the configuration.
3
+ # You can use this file by the following command line on Debian GNU/Linux
4
+ # or Ubuntu:
5
+ #
6
+ # % sudo -H ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/dyngroup.ldif
7
+ # % sudo -H ldapmodify -Y EXTERNAL -H ldapi:/// -f test/enable-dynamic-groups.ldif
8
+ version: 1
9
+
10
+ # Enable dynlist module
11
+ dn: cn=module{0},cn=config
12
+ changetype: modify
13
+ add: olcModuleLoad
14
+ olcModuleLoad: dynlist
15
+
16
+ # Set up dynlist overlay
17
+ dn: olcOverlay=dynlist,olcDatabase={1}mdb,cn=config
18
+ changetype: add
19
+ objectClass: olcOverlayConfig
20
+ objectClass: olcDynamicList
21
+ olcOverlay: dynlist
22
+ olcDlAttrSet: groupOfURLs memberURL member
@@ -1,6 +1,6 @@
1
1
  # Your LDAP server needs to support StartTLS when you test StartTLS related
2
2
  # feature. This is a LDIF file for OpenLDAP to do the configuration.
3
- # You can use this file by the following command linne on Debian GNU/Linux
3
+ # You can use this file by the following command line on Debian GNU/Linux
4
4
  # or Ubuntu:
5
5
  #
6
6
  # % sudo usermod -a -G ssl-cert openldap
data/test/run-test.rb CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  $VERBOSE = true
4
4
 
5
- $KCODE = 'u' if RUBY_VERSION < "1.9"
6
-
7
5
  base_dir = File.expand_path(File.dirname(__FILE__))
8
6
  top_dir = File.expand_path(File.join(base_dir, ".."))
9
7
  lib_dir = File.join(top_dir, "lib")
@@ -11,11 +9,9 @@ test_dir = File.join(top_dir, "test")
11
9
  $LOAD_PATH.unshift(lib_dir)
12
10
  $LOAD_PATH.unshift(test_dir)
13
11
 
14
- require "rubygems"
15
12
  require "bundler/setup"
16
13
 
17
14
  require "test/unit"
18
- require "test/unit/notify"
19
15
  Test::Unit::Priority.enable
20
16
 
21
17
  Dir.glob(File.join(test_dir, "**", "test_*.rb")) do |test_file|
data/test/test_base.rb CHANGED
@@ -5,7 +5,52 @@ require 'al-test-utils'
5
5
  class TestBase < Test::Unit::TestCase
6
6
  include AlTestUtils
7
7
 
8
+ sub_test_case("follow_referrals") do
9
+ def test_default
10
+ make_temporary_user do |user1,|
11
+ make_temporary_user do |user2,|
12
+ member_url = ["ldap:///#{user1.base.to_s}??one?(objectClass=person)"]
13
+ make_temporary_group_of_urls(member_url: member_url) do |group_of_urls|
14
+ assert_equal([user1.dn, user2.dn],
15
+ group_of_urls.attributes["member"])
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ def test_connection_false
22
+ omit_unless_jruby
23
+ @group_of_urls_class.setup_connection(
24
+ current_configuration.merge(follow_referrals: false)
25
+ )
26
+ make_temporary_user do |user1,|
27
+ make_temporary_user do |user2,|
28
+ member_url = ["ldap:///#{user1.base.to_s}??one?(objectClass=person)"]
29
+ make_temporary_group_of_urls(member_url: member_url) do |group_of_urls|
30
+ assert_nil(group_of_urls.attributes["member"])
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def test_connect_false
37
+ omit_unless_jruby
38
+ connection = @group_of_urls_class.connection
39
+ connection.disconnect!
40
+ connection.connect(follow_referrals: false)
41
+ make_temporary_user do |user1,|
42
+ make_temporary_user do |user2,|
43
+ member_url = ["ldap:///#{user1.base.to_s}??one?(objectClass=person)"]
44
+ make_temporary_group_of_urls(member_url: member_url) do |group_of_urls|
45
+ assert_nil(group_of_urls.attributes["member"])
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+
8
52
  priority :must
53
+ priority :normal
9
54
  def test_search_colon_value
10
55
  make_temporary_group(:cn => "temp:group") do |group|
11
56
  assert_equal("temp:group", group.cn)
@@ -13,7 +58,6 @@ class TestBase < Test::Unit::TestCase
13
58
  end
14
59
  end
15
60
 
16
- priority :normal
17
61
  def test_lower_case_object_class
18
62
  fixture_file = fixture("lower_case_object_class_schema.rb")
19
63
  schema_entries = eval(File.read(fixture_file))
@@ -122,9 +166,9 @@ class TestBase < Test::Unit::TestCase
122
166
 
123
167
  def test_operational_attributes
124
168
  make_temporary_group do |group|
125
- dn, attributes = @group_class.search(:attributes => ["*"])[0]
169
+ _dn, attributes = @group_class.search(:attributes => ["*"])[0]
126
170
  normal_attributes = attributes.keys
127
- dn, attributes = @group_class.search(:attributes => ["*", "+"])[0]
171
+ _dn, attributes = @group_class.search(:attributes => ["*", "+"])[0]
128
172
  operational_attributes = attributes.keys - normal_attributes
129
173
  operational_attribute = operational_attributes[0]
130
174
 
@@ -150,13 +194,13 @@ class TestBase < Test::Unit::TestCase
150
194
  _ou_class.create("root2")
151
195
  assert_equal(["base",
152
196
  "root1", "child1", "child2", "domain", "child3",
153
- "root2"],
154
- _entry_class.find(:all).collect(&:id))
197
+ "root2"].sort,
198
+ _entry_class.find(:all).collect(&:id).sort)
155
199
  assert_raise(ActiveLdap::DeleteError) do
156
200
  root1.destroy_all
157
201
  end
158
- assert_equal(["base", "root1", "domain", "root2"],
159
- _entry_class.find(:all).collect(&:id))
202
+ assert_equal(["base", "root1", "domain", "root2"].sort,
203
+ _entry_class.find(:all).collect(&:id).sort)
160
204
  end
161
205
 
162
206
  def test_delete_mixed_tree_by_instance
@@ -173,13 +217,13 @@ class TestBase < Test::Unit::TestCase
173
217
  _ou_class.create("root2")
174
218
  assert_equal(["base",
175
219
  "root1", "child1", "child2", "domain", "child3",
176
- "root2"],
177
- _entry_class.find(:all).collect(&:id))
220
+ "root2"].sort,
221
+ _entry_class.find(:all).collect(&:id).sort)
178
222
  assert_raise(ActiveLdap::DeleteError) do
179
223
  root1.delete_all
180
224
  end
181
- assert_equal(["base", "root1", "domain", "root2"],
182
- _entry_class.find(:all).collect(&:id))
225
+ assert_equal(["base", "root1", "domain", "root2"].sort,
226
+ _entry_class.find(:all).collect(&:id).sort)
183
227
  end
184
228
 
185
229
  def test_delete_tree
@@ -189,8 +233,8 @@ class TestBase < Test::Unit::TestCase
189
233
  _ou_class.create(:ou => "child1", :parent => root1)
190
234
  _ou_class.create(:ou => "child2", :parent => root1)
191
235
  _ou_class.create("root2")
192
- assert_equal(["base", "root1", "child1", "child2", "root2"],
193
- _ou_class.find(:all).collect(&:ou))
236
+ assert_equal(["base", "root1", "child1", "child2", "root2"].sort,
237
+ _ou_class.find(:all).collect(&:ou).sort)
194
238
  _ou_class.delete_all(:base => root1.dn)
195
239
  assert_equal(["base", "root2"],
196
240
  _ou_class.find(:all).collect(&:ou))
@@ -217,11 +261,11 @@ class TestBase < Test::Unit::TestCase
217
261
  :classes => ["top"]
218
262
  entry_class.dn_attribute = nil
219
263
  assert_equal(["base", "root1", "child1", "domain1", "grandchild1",
220
- "child2", "domain2", "root2"],
221
- entry_class.find(:all).collect(&:id))
264
+ "child2", "domain2", "root2"].sort,
265
+ entry_class.find(:all).collect(&:id).sort)
222
266
  entry_class.delete_all(nil, :base => child2.dn)
223
- assert_equal(["base", "root1", "child1", "domain1", "grandchild1", "root2"],
224
- entry_class.find(:all).collect(&:id))
267
+ assert_equal(["base", "root1", "child1", "domain1", "grandchild1", "root2"].sort,
268
+ entry_class.find(:all).collect(&:id).sort)
225
269
  end
226
270
 
227
271
  def test_first
@@ -383,6 +427,19 @@ class TestBase < Test::Unit::TestCase
383
427
  end
384
428
  end
385
429
 
430
+ def test_set_dn_with_unnormalized_dn_attribute_with_forward_slash
431
+ make_temporary_user do |user,|
432
+ new_dn = "uid=temp/user1,#{user.class.base}"
433
+ assert_not_equal(user.dn.to_s, new_dn)
434
+
435
+ user.uid = 'temp/user1'
436
+ assert_equal(user.dn.to_s, new_dn)
437
+
438
+ assert_true(user.save!)
439
+ assert_true(user.class.find(user.uid).update_attributes!(gidNumber: 100069))
440
+ end
441
+ end
442
+
386
443
  def test_destroy_with_empty_base_and_prefix_of_class
387
444
  make_temporary_user do |user,|
388
445
  base = user.class.base
@@ -945,7 +1002,8 @@ class TestBase < Test::Unit::TestCase
945
1002
  ou_class.ldap_mapping(:dn_attribute => :ou,
946
1003
  :prefix => "",
947
1004
  :classes => ["top", "organizationalUnit"])
948
- assert_equal(["ou=Groups,#{current_configuration['base']}",
1005
+ assert_equal(["ou=GroupOfURLsSet,#{current_configuration['base']}",
1006
+ "ou=Groups,#{current_configuration['base']}",
949
1007
  "ou=Users,#{current_configuration['base']}"],
950
1008
  ou_class.find(:all).collect(&:dn).collect(&:to_s).sort)
951
1009
  end
@@ -9,13 +9,45 @@ class TestBasePerInstance < Test::Unit::TestCase
9
9
  end
10
10
 
11
11
  priority :must
12
+ def test_dn_with_sub_base_first
13
+ sub_user = @user_class.new(dn: "uid=user1,ou=Sub,#{@user_class.base}",
14
+ uid: "user1")
15
+ # Order is important. #base should be called before #dn.
16
+ base = sub_user.base.to_s
17
+ dn = sub_user.dn.to_s
18
+ assert_equal([
19
+ "ou=Sub,#{@user_class.base}",
20
+ "uid=user1,ou=Sub,#{@user_class.base}",
21
+ ],
22
+ [
23
+ base,
24
+ dn,
25
+ ])
26
+ end
27
+
28
+ def test_dn_with_sub_base_last
29
+ sub_user = @user_class.new(uid: "user1",
30
+ dn: "uid=user1,ou=Sub,#{@user_class.base}")
31
+ # Order is important. #base should be called before #dn.
32
+ base = sub_user.base.to_s
33
+ dn = sub_user.dn.to_s
34
+ assert_equal([
35
+ "ou=Sub,#{@user_class.base}",
36
+ "uid=user1,ou=Sub,#{@user_class.base}",
37
+ ],
38
+ [
39
+ base,
40
+ dn,
41
+ ])
42
+ end
43
+
44
+ priority :normal
12
45
  def test_set_base
13
46
  guest = @user_class.new("guest")
14
47
  guest.base = "ou=Sub"
15
48
  assert_equal("uid=guest,ou=Sub,#{@user_class.base}", guest.dn)
16
49
  end
17
50
 
18
- priority :normal
19
51
  def test_dn_is_base
20
52
  entry_class = Class.new(ActiveLdap::Base)
21
53
  entry_class.ldap_mapping :prefix => "",
@@ -3,6 +3,7 @@ require 'al-test-utils'
3
3
  class TestConnection < Test::Unit::TestCase
4
4
  include AlTestUtils::Config
5
5
  include AlTestUtils::MockLogger
6
+ include AlTestUtils::Omittable
6
7
 
7
8
  def setup
8
9
  super
@@ -23,6 +24,9 @@ class TestConnection < Test::Unit::TestCase
23
24
  end
24
25
 
25
26
  def test_retry_limit_0_with_nonexistent_host_with_timeout
27
+ omit_if_ldap("this test will take a long time...")
28
+ omit_if_jruby("JNI adapter returns connection error immediately. " +
29
+ "So timeout isn't invoked.")
26
30
  config = current_configuration.merge("host" => "192.168.29.29",
27
31
  "retry_limit" => 0,
28
32
  "timeout" => 1)
data/test/test_entry.rb CHANGED
@@ -11,6 +11,7 @@ class TestEntry < Test::Unit::TestCase
11
11
  all_entries = [ActiveLdap::Base.base]
12
12
  all_entries += [user.dn, user.base]
13
13
  all_entries += [group.dn, group.base]
14
+ all_entries += [@group_of_urls_class.base]
14
15
  assert_equal(all_entries.sort,
15
16
  ActiveLdap::Entry.all.collect(&:dn).sort)
16
17
  end
data/test/test_find.rb CHANGED
@@ -3,7 +3,18 @@ require 'al-test-utils'
3
3
  class TestFind < Test::Unit::TestCase
4
4
  include AlTestUtils
5
5
 
6
- priority :must
6
+ def test_find_paged
7
+ page_size = 126
8
+ n_users = page_size + 1
9
+ uids = n_users.times.collect do
10
+ user, _password = make_temporary_user
11
+ user.uid
12
+ end
13
+ users = @user_class.find(:all, page_size: page_size)
14
+ assert_equal(uids.sort,
15
+ users.collect(&:uid).sort)
16
+ end
17
+
7
18
  def test_find_with_dn
8
19
  make_temporary_user do |user,|
9
20
  assert_equal(user.dn, @user_class.find(user.dn).dn)
@@ -11,7 +22,6 @@ class TestFind < Test::Unit::TestCase
11
22
  end
12
23
  end
13
24
 
14
- priority :normal
15
25
  def test_find_with_special_value_prefix
16
26
  # \2C == ','
17
27
  make_ou("a\\2Cb,ou=Users")
@@ -17,7 +17,7 @@ class TestSupportedControl < Test::Unit::TestCase
17
17
  end
18
18
 
19
19
  def test_false
20
- assert_true(paged_results?(ActiveLdap::LdapControls::PAGED_RESULTS))
20
+ assert_false(paged_results?(ActiveLdap::LdapControls::ASSERTION))
21
21
  end
22
22
  end
23
23
  end