activeldap 5.2.3 → 6.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.yardopts +3 -1
- data/doc/text/development.md +26 -0
- data/doc/text/{news.textile → news.md} +345 -271
- data/doc/text/{rails.textile → rails.md} +35 -33
- data/doc/text/{tutorial.textile → tutorial.md} +177 -185
- data/lib/active_ldap.rb +0 -1
- data/lib/active_ldap/adapter/base.rb +29 -10
- data/lib/active_ldap/adapter/jndi.rb +21 -9
- data/lib/active_ldap/adapter/jndi_connection.rb +83 -20
- data/lib/active_ldap/adapter/ldap.rb +13 -22
- data/lib/active_ldap/adapter/ldap_ext.rb +32 -13
- data/lib/active_ldap/adapter/net_ldap.rb +9 -18
- data/lib/active_ldap/base.rb +11 -1
- data/lib/active_ldap/configuration.rb +24 -1
- data/lib/active_ldap/connection.rb +1 -1
- data/lib/active_ldap/human_readable.rb +5 -4
- data/lib/active_ldap/operations.rb +21 -4
- data/lib/active_ldap/persistence.rb +3 -2
- data/lib/active_ldap/validations.rb +12 -4
- data/lib/active_ldap/version.rb +1 -1
- data/test/add-phonetic-attribute-options-to-slapd.ldif +1 -1
- data/test/al-test-utils.rb +125 -38
- data/test/enable-dynamic-groups.ldif +22 -0
- data/test/enable-start-tls.ldif +1 -1
- data/test/run-test.rb +0 -4
- data/test/test_base.rb +76 -18
- data/test/test_base_per_instance.rb +33 -1
- data/test/test_connection.rb +4 -0
- data/test/test_entry.rb +1 -0
- data/test/test_find.rb +12 -2
- data/test/test_supported_control.rb +1 -1
- data/test/test_validation.rb +28 -15
- metadata +18 -32
- data/README.textile +0 -141
- data/doc/text/development.textile +0 -54
data/lib/active_ldap/base.rb
CHANGED
|
@@ -851,6 +851,8 @@ module ActiveLdap
|
|
|
851
851
|
|
|
852
852
|
_schema = _local_entry_attribute = nil
|
|
853
853
|
targets = sanitize_for_mass_assignment(new_attributes)
|
|
854
|
+
have_dn = false
|
|
855
|
+
dn_value = nil
|
|
854
856
|
targets.each do |key, value|
|
|
855
857
|
setter = "#{key}="
|
|
856
858
|
unless respond_to?(setter)
|
|
@@ -860,8 +862,15 @@ module ActiveLdap
|
|
|
860
862
|
_local_entry_attribute ||= local_entry_attribute
|
|
861
863
|
_local_entry_attribute.register(attribute)
|
|
862
864
|
end
|
|
863
|
-
|
|
865
|
+
case setter
|
|
866
|
+
when "dn=", "id="
|
|
867
|
+
have_dn = true
|
|
868
|
+
dn_value = value
|
|
869
|
+
else
|
|
870
|
+
send(setter, value)
|
|
871
|
+
end
|
|
864
872
|
end
|
|
873
|
+
self.dn = dn_value if have_dn
|
|
865
874
|
end
|
|
866
875
|
|
|
867
876
|
def to_ldif_record
|
|
@@ -1281,6 +1290,7 @@ module ActiveLdap
|
|
|
1281
1290
|
end
|
|
1282
1291
|
|
|
1283
1292
|
def compute_base
|
|
1293
|
+
ensure_update_dn
|
|
1284
1294
|
base_of_class = self.class.base
|
|
1285
1295
|
if @base_value.nil?
|
|
1286
1296
|
base_of_class
|
|
@@ -48,6 +48,15 @@ module ActiveLdap
|
|
|
48
48
|
DEFAULT_CONFIG[:retry_on_timeout] = true
|
|
49
49
|
DEFAULT_CONFIG[:follow_referrals] = true
|
|
50
50
|
|
|
51
|
+
# 500 is the default size limit value of OpenLDAP 2.4:
|
|
52
|
+
# https://openldap.org/doc/admin24/limits.html#Global%20Limits
|
|
53
|
+
#
|
|
54
|
+
# We may change this when we find LDAP server that its the default
|
|
55
|
+
# size limit is smaller than 500.
|
|
56
|
+
DEFAULT_CONFIG[:page_size] = 500
|
|
57
|
+
# Whether using paged results if available.
|
|
58
|
+
DEFAULT_CONFIG[:use_paged_results] = true
|
|
59
|
+
|
|
51
60
|
DEFAULT_CONFIG[:logger] = nil
|
|
52
61
|
|
|
53
62
|
module ClassMethods
|
|
@@ -103,8 +112,22 @@ module ActiveLdap
|
|
|
103
112
|
end
|
|
104
113
|
end
|
|
105
114
|
|
|
115
|
+
def parent_configuration(target)
|
|
116
|
+
if target.is_a?(Base)
|
|
117
|
+
target = target.class
|
|
118
|
+
else
|
|
119
|
+
target = target.superclass
|
|
120
|
+
end
|
|
121
|
+
while target <= Base
|
|
122
|
+
config = defined_configurations[target.active_connection_key]
|
|
123
|
+
return config if config
|
|
124
|
+
target = target.superclass
|
|
125
|
+
end
|
|
126
|
+
default_configuration
|
|
127
|
+
end
|
|
128
|
+
|
|
106
129
|
def merge_configuration(user_configuration, target=self)
|
|
107
|
-
configuration =
|
|
130
|
+
configuration = parent_configuration(target).dup
|
|
108
131
|
prepare_configuration(user_configuration).each do |key, value|
|
|
109
132
|
case key
|
|
110
133
|
when :base
|
|
@@ -165,11 +165,11 @@ module ActiveLdap
|
|
|
165
165
|
connection.schema
|
|
166
166
|
end
|
|
167
167
|
|
|
168
|
-
private
|
|
169
168
|
def active_connection_key(k=self)
|
|
170
169
|
k.name.blank? ? k.object_id : k.name
|
|
171
170
|
end
|
|
172
171
|
|
|
172
|
+
private
|
|
173
173
|
def determine_active_connection_name
|
|
174
174
|
key = active_connection_key
|
|
175
175
|
if active_connections[key] or configuration(key)
|
|
@@ -17,11 +17,12 @@ module ActiveLdap
|
|
|
17
17
|
if attribute_or_name.is_a?(Schema::Attribute)
|
|
18
18
|
name = attribute_or_name.name
|
|
19
19
|
else
|
|
20
|
-
|
|
20
|
+
attribute_name = attribute_or_name.to_s
|
|
21
|
+
attribute = schema.attribute(attribute_name)
|
|
21
22
|
return nil if attribute.id.nil?
|
|
22
|
-
if attribute.name ==
|
|
23
|
-
attribute.aliases.include?(
|
|
24
|
-
name =
|
|
23
|
+
if attribute.name == attribute_name or
|
|
24
|
+
attribute.aliases.include?(attribute_name)
|
|
25
|
+
name = attribute_name
|
|
25
26
|
else
|
|
26
27
|
return nil
|
|
27
28
|
end
|
|
@@ -22,9 +22,23 @@ module ActiveLdap
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
module Common
|
|
25
|
-
VALID_SEARCH_OPTIONS = [
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
VALID_SEARCH_OPTIONS = [
|
|
26
|
+
:attribute,
|
|
27
|
+
:value,
|
|
28
|
+
:filter,
|
|
29
|
+
:prefix,
|
|
30
|
+
:classes,
|
|
31
|
+
:scope,
|
|
32
|
+
:limit,
|
|
33
|
+
:attributes,
|
|
34
|
+
:sort_by,
|
|
35
|
+
:order,
|
|
36
|
+
:connection,
|
|
37
|
+
:base,
|
|
38
|
+
:offset,
|
|
39
|
+
:use_paged_results,
|
|
40
|
+
:page_size,
|
|
41
|
+
]
|
|
28
42
|
|
|
29
43
|
def search(options={}, &block)
|
|
30
44
|
validate_search_options(options)
|
|
@@ -62,6 +76,8 @@ module ActiveLdap
|
|
|
62
76
|
:attributes => requested_attributes,
|
|
63
77
|
:sort_by => options[:sort_by] || sort_by,
|
|
64
78
|
:order => options[:order] || order,
|
|
79
|
+
:use_paged_results => options[:use_paged_results],
|
|
80
|
+
:page_size => options[:page_size],
|
|
65
81
|
}
|
|
66
82
|
options[:connection] ||= connection
|
|
67
83
|
values = []
|
|
@@ -96,10 +112,11 @@ module ActiveLdap
|
|
|
96
112
|
}
|
|
97
113
|
|
|
98
114
|
attribute = attr || ensure_search_attribute
|
|
115
|
+
escaped_value = DN.escape_value(value)
|
|
99
116
|
options_for_non_leaf = {
|
|
100
117
|
:attribute => attr,
|
|
101
118
|
:value => value,
|
|
102
|
-
:prefix => ["#{attribute}=#{
|
|
119
|
+
:prefix => ["#{attribute}=#{escaped_value}", prefix].compact.join(","),
|
|
103
120
|
:limit => 1,
|
|
104
121
|
:scope => :base,
|
|
105
122
|
}
|
|
@@ -81,9 +81,10 @@ module ActiveLdap
|
|
|
81
81
|
end
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
def reload
|
|
84
|
+
def reload(options={})
|
|
85
85
|
clear_association_cache
|
|
86
|
-
|
|
86
|
+
search_options = options.merge(value: id)
|
|
87
|
+
_, attributes = search(search_options).find do |_dn, _attributes|
|
|
87
88
|
dn == _dn
|
|
88
89
|
end
|
|
89
90
|
if attributes.nil?
|
|
@@ -53,15 +53,23 @@ module ActiveLdap
|
|
|
53
53
|
errors.empty? && output
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
def save(
|
|
57
|
-
|
|
56
|
+
def save(**options)
|
|
57
|
+
perform_validations(options) ? super : false
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def save!(
|
|
61
|
-
|
|
60
|
+
def save!(**options)
|
|
61
|
+
perform_validations(options) ? super : raise(EntryInvalid.new(self))
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
private
|
|
65
|
+
def perform_validations(options)
|
|
66
|
+
if options[:validate] == false
|
|
67
|
+
true
|
|
68
|
+
else
|
|
69
|
+
valid?(options[:context])
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
65
73
|
def format_validation_message(format, parameters)
|
|
66
74
|
format % parameters
|
|
67
75
|
end
|
data/lib/active_ldap/version.rb
CHANGED
|
@@ -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
|
|
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
|
data/test/al-test-utils.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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
|
-
|
|
338
|
-
|
|
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
|