treequel 1.0.1 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +176 -14
- data/LICENSE +1 -1
- data/Rakefile +61 -45
- data/Rakefile.local +20 -0
- data/bin/treequel +502 -269
- data/examples/ldap-rack-auth.rb +2 -0
- data/lib/treequel.rb +221 -18
- data/lib/treequel/branch.rb +410 -201
- data/lib/treequel/branchcollection.rb +25 -13
- data/lib/treequel/branchset.rb +42 -40
- data/lib/treequel/constants.rb +233 -3
- data/lib/treequel/control.rb +95 -0
- data/lib/treequel/controls/contentsync.rb +138 -0
- data/lib/treequel/controls/pagedresults.rb +162 -0
- data/lib/treequel/controls/sortedresults.rb +216 -0
- data/lib/treequel/directory.rb +212 -65
- data/lib/treequel/exceptions.rb +11 -12
- data/lib/treequel/filter.rb +1 -12
- data/lib/treequel/mixins.rb +83 -47
- data/lib/treequel/monkeypatches.rb +29 -0
- data/lib/treequel/schema.rb +23 -19
- data/lib/treequel/schema/attributetype.rb +33 -3
- data/lib/treequel/schema/ldapsyntax.rb +0 -11
- data/lib/treequel/schema/matchingrule.rb +0 -11
- data/lib/treequel/schema/matchingruleuse.rb +0 -11
- data/lib/treequel/schema/objectclass.rb +36 -10
- data/lib/treequel/schema/table.rb +159 -0
- data/lib/treequel/sequel_integration.rb +7 -7
- data/lib/treequel/utils.rb +4 -66
- data/rake/documentation.rb +89 -0
- data/rake/helpers.rb +375 -307
- data/rake/hg.rb +16 -2
- data/rake/manual.rb +11 -6
- data/rake/packaging.rb +20 -35
- data/rake/publishing.rb +22 -62
- data/spec/lib/constants.rb +20 -0
- data/spec/lib/control_behavior.rb +44 -0
- data/spec/lib/matchers.rb +51 -0
- data/spec/treequel/branch_spec.rb +88 -29
- data/spec/treequel/branchcollection_spec.rb +24 -1
- data/spec/treequel/branchset_spec.rb +123 -51
- data/spec/treequel/control_spec.rb +48 -0
- data/spec/treequel/controls/contentsync_spec.rb +38 -0
- data/spec/treequel/controls/pagedresults_spec.rb +138 -0
- data/spec/treequel/controls/sortedresults_spec.rb +171 -0
- data/spec/treequel/directory_spec.rb +186 -16
- data/spec/treequel/mixins_spec.rb +42 -3
- data/spec/treequel/schema/attributetype_spec.rb +22 -20
- data/spec/treequel/schema/objectclass_spec.rb +67 -46
- data/spec/treequel/schema/table_spec.rb +134 -0
- data/spec/treequel_spec.rb +277 -15
- metadata +89 -108
- data/bin/treequel.orig +0 -963
- data/examples/ldap-monitor.rb +0 -143
- data/examples/ldap-monitor/public/css/master.css +0 -328
- data/examples/ldap-monitor/public/images/card_small.png +0 -0
- data/examples/ldap-monitor/public/images/chain_small.png +0 -0
- data/examples/ldap-monitor/public/images/globe_small.png +0 -0
- data/examples/ldap-monitor/public/images/globe_small_green.png +0 -0
- data/examples/ldap-monitor/public/images/plug.png +0 -0
- data/examples/ldap-monitor/public/images/shadows/large-30-down.png +0 -0
- data/examples/ldap-monitor/public/images/tick.png +0 -0
- data/examples/ldap-monitor/public/images/tick_circle.png +0 -0
- data/examples/ldap-monitor/public/images/treequel-favicon.png +0 -0
- data/examples/ldap-monitor/views/backends.erb +0 -41
- data/examples/ldap-monitor/views/connections.erb +0 -74
- data/examples/ldap-monitor/views/databases.erb +0 -39
- data/examples/ldap-monitor/views/dump_subsystem.erb +0 -14
- data/examples/ldap-monitor/views/index.erb +0 -14
- data/examples/ldap-monitor/views/layout.erb +0 -35
- data/examples/ldap-monitor/views/listeners.erb +0 -30
- data/rake/rdoc.rb +0 -30
- data/rake/win32.rb +0 -190
data/lib/treequel/directory.rb
CHANGED
@@ -13,18 +13,6 @@ require 'treequel/constants'
|
|
13
13
|
|
14
14
|
# The object in Treequel that represents a connection to a directory, the
|
15
15
|
# binding to that directory, and the base from which all DNs start.
|
16
|
-
#
|
17
|
-
# == Authors
|
18
|
-
#
|
19
|
-
# * Michael Granger <ged@FaerieMUD.org>
|
20
|
-
# * Mahlon E. Smith <mahlon@martini.nu>
|
21
|
-
#
|
22
|
-
# :include: LICENSE
|
23
|
-
#
|
24
|
-
#--
|
25
|
-
#
|
26
|
-
# Please see the file LICENSE in the base directory for licensing details.
|
27
|
-
#
|
28
16
|
class Treequel::Directory
|
29
17
|
include Treequel::Loggable,
|
30
18
|
Treequel::Constants,
|
@@ -99,33 +87,37 @@ class Treequel::Directory
|
|
99
87
|
|
100
88
|
### Create a new Treequel::Directory with the given +options+. Options is a hash with one
|
101
89
|
### or more of the following key-value pairs:
|
102
|
-
###
|
103
|
-
### [
|
104
|
-
###
|
105
|
-
###
|
106
|
-
###
|
107
|
-
###
|
108
|
-
###
|
109
|
-
###
|
110
|
-
###
|
111
|
-
###
|
112
|
-
###
|
113
|
-
### [:
|
114
|
-
###
|
90
|
+
###
|
91
|
+
### @param [Hash] options the connection options
|
92
|
+
### @option options [String] :host ('localhost')
|
93
|
+
### The LDAP host to connect to
|
94
|
+
### @option options [Fixnum] :port (LDAP::LDAP_PORT)
|
95
|
+
### The port number to connect to
|
96
|
+
### @option options [Symbol] :connect_type (:tls)
|
97
|
+
### The type of connection to establish; :tls, :ssl, or :plain.
|
98
|
+
### @option options [String] :base_dn (nil)
|
99
|
+
### The base DN of the directory; defaults to the first naming context of
|
100
|
+
### the directory's root DSE.
|
101
|
+
### @option options [String] :bind_dn (nil)
|
102
|
+
### The DN of the user to bind as; if unset, binds anonymously.
|
103
|
+
### @option options [String] :pass (nil)
|
104
|
+
### The password to use when binding.
|
115
105
|
def initialize( options={} )
|
116
|
-
options
|
106
|
+
options = DEFAULT_OPTIONS.merge( options )
|
117
107
|
|
118
|
-
@host
|
119
|
-
@port
|
120
|
-
@connect_type
|
108
|
+
@host = options[:host]
|
109
|
+
@port = options[:port]
|
110
|
+
@connect_type = options[:connect_type]
|
121
111
|
|
122
|
-
@conn
|
123
|
-
@
|
112
|
+
@conn = nil
|
113
|
+
@bound_user = nil
|
124
114
|
|
125
|
-
@base_dn
|
126
|
-
@syntax_mapping = DEFAULT_SYNTAX_MAPPING.dup
|
115
|
+
@base_dn = options[:base_dn] || self.get_default_base_dn
|
127
116
|
|
128
|
-
@base
|
117
|
+
@base = nil
|
118
|
+
|
119
|
+
@syntax_mapping = DEFAULT_SYNTAX_MAPPING.dup
|
120
|
+
@registered_controls = []
|
129
121
|
|
130
122
|
# Immediately bind if credentials are passed to the initializer.
|
131
123
|
if ( options[:bind_dn] && options[:pass] )
|
@@ -141,38 +133,57 @@ class Treequel::Directory
|
|
141
133
|
# Delegate some methods to the #base Branch.
|
142
134
|
def_method_delegators :base, *DELEGATED_BRANCH_METHODS
|
143
135
|
|
136
|
+
# Delegate some methods to the connection via the #conn method
|
137
|
+
def_method_delegators :conn, :controls, :referrals
|
138
|
+
|
139
|
+
|
144
140
|
# The host to connect to.
|
141
|
+
# @return [String]
|
145
142
|
attr_accessor :host
|
146
143
|
|
147
144
|
# The port to connect to.
|
145
|
+
# @return [Fixnum]
|
148
146
|
attr_accessor :port
|
149
147
|
|
150
148
|
# The type of connection to establish
|
149
|
+
# @return [Symbol]
|
151
150
|
attr_accessor :connect_type
|
152
151
|
|
153
152
|
# The base DN of the directory
|
153
|
+
# @return [String]
|
154
154
|
attr_accessor :base_dn
|
155
155
|
|
156
|
+
# The control modules that are registered with the directory
|
157
|
+
# @return [Array<Module>]
|
158
|
+
attr_reader :registered_controls
|
159
|
+
|
160
|
+
# The DN of the user the directory is bound as
|
161
|
+
# @return [String]
|
162
|
+
attr_reader :bound_user
|
163
|
+
|
156
164
|
|
157
165
|
### Fetch the Branch for the base node of the directory.
|
166
|
+
### @return [Treequel::Branch]
|
158
167
|
def base
|
159
168
|
return @base ||= Treequel::Branch.new( self, self.base_dn )
|
160
169
|
end
|
161
170
|
|
162
171
|
|
163
172
|
### Returns a string that describes the directory
|
173
|
+
### @return [String]
|
164
174
|
def to_s
|
165
175
|
return "%s:%d (%s, %s, %s)" % [
|
166
176
|
self.host,
|
167
177
|
self.port,
|
168
178
|
self.base_dn,
|
169
179
|
self.connect_type,
|
170
|
-
self.bound? ? @
|
180
|
+
self.bound? ? @bound_user : 'anonymous'
|
171
181
|
]
|
172
182
|
end
|
173
183
|
|
174
184
|
|
175
185
|
### Return a human-readable representation of the object suitable for debugging
|
186
|
+
### @return [String]
|
176
187
|
def inspect
|
177
188
|
return %{#<%s:0x%0x %s:%d (%s) base_dn=%p, bound as=%s, schema=%s>} % [
|
178
189
|
self.class.name,
|
@@ -181,7 +192,7 @@ class Treequel::Directory
|
|
181
192
|
self.port,
|
182
193
|
@conn ? "connected" : "not connected",
|
183
194
|
self.base_dn,
|
184
|
-
@
|
195
|
+
@bound_user ? @bound_user.dump : "anonymous",
|
185
196
|
@schema ? @schema.inspect : "(schema not loaded)",
|
186
197
|
]
|
187
198
|
end
|
@@ -189,12 +200,14 @@ class Treequel::Directory
|
|
189
200
|
|
190
201
|
### Return the LDAP::Conn object associated with this directory, creating it with the
|
191
202
|
### current options if necessary.
|
203
|
+
### @return [LDAP::Conn, LDAP::SSLConn]
|
192
204
|
def conn
|
193
205
|
return @conn ||= self.connect
|
194
206
|
end
|
195
207
|
|
196
208
|
|
197
209
|
### Return the URI object that corresponds to the directory.
|
210
|
+
### @return [URI::LDAP]
|
198
211
|
def uri
|
199
212
|
uri_parts = {
|
200
213
|
:scheme => self.connect_type == :ssl ? 'ldaps' : 'ldap',
|
@@ -208,30 +221,41 @@ class Treequel::Directory
|
|
208
221
|
|
209
222
|
|
210
223
|
### Bind as the specified +user_dn+ and +password+.
|
224
|
+
###
|
225
|
+
### @param [String, #dn] user_dn the DN of the user to bind as
|
226
|
+
### @param [String] password the password to bind with
|
227
|
+
###
|
228
|
+
### @return [void]
|
211
229
|
def bind( user_dn, password )
|
212
230
|
user_dn = user_dn.dn if user_dn.respond_to?( :dn )
|
213
231
|
|
214
232
|
self.log.info "Binding with connection %p as: %s" % [ self.conn, user_dn ]
|
215
233
|
self.conn.bind( user_dn.to_s, password )
|
216
|
-
@
|
234
|
+
@bound_user = user_dn.to_s
|
217
235
|
end
|
236
|
+
alias_method :bind_as, :bind
|
218
237
|
|
219
238
|
|
220
239
|
### Execute the provided +block+ after binding as +user_dn+ with the given +password+. After
|
221
240
|
### the block returns, the original binding (if any) will be restored.
|
241
|
+
###
|
242
|
+
### @param (see #bind)
|
243
|
+
###
|
244
|
+
### @return [void]
|
222
245
|
def bound_as( user_dn, password )
|
223
246
|
raise LocalJumpError, "no block given" unless block_given?
|
224
|
-
previous_bind_dn = @
|
247
|
+
previous_bind_dn = @bound_user
|
225
248
|
self.with_duplicate_conn do
|
226
249
|
self.bind( user_dn, password )
|
227
250
|
yield
|
228
251
|
end
|
229
252
|
ensure
|
230
|
-
@
|
253
|
+
@bound_user = previous_bind_dn
|
231
254
|
end
|
232
255
|
|
233
256
|
|
234
|
-
### Returns +true+ if the directory's connection
|
257
|
+
### Returns +true+ if the directory's connection is already bound to the directory.
|
258
|
+
### @return [Boolean]
|
235
259
|
def bound?
|
236
260
|
return self.conn.bound?
|
237
261
|
end
|
@@ -239,6 +263,7 @@ class Treequel::Directory
|
|
239
263
|
|
240
264
|
|
241
265
|
### Ensure that the the receiver's connection is unbound.
|
266
|
+
### @return [void]
|
242
267
|
def unbind
|
243
268
|
if @conn.bound?
|
244
269
|
old_conn = @conn
|
@@ -249,6 +274,7 @@ class Treequel::Directory
|
|
249
274
|
|
250
275
|
|
251
276
|
### Return the RDN string to the given +dn+ from the base of the directory.
|
277
|
+
### @param [#to_s] dn the DN of the entry
|
252
278
|
def rdn_to( dn )
|
253
279
|
base_re = Regexp.new( ',' + Regexp.quote(self.base_dn) + '$' )
|
254
280
|
return dn.to_s.sub( base_re, '' )
|
@@ -257,6 +283,8 @@ class Treequel::Directory
|
|
257
283
|
|
258
284
|
### Given a Treequel::Branch object, find its corresponding LDAP::Entry and return
|
259
285
|
### it.
|
286
|
+
###
|
287
|
+
### @param [Treequel::Branch] branch the branch to look up
|
260
288
|
def get_entry( branch )
|
261
289
|
self.log.debug "Looking up entry for %p" % [ branch.dn ]
|
262
290
|
return self.conn.search_ext2( branch.dn, SCOPE[:base], '(objectClass=*)' ).first
|
@@ -269,6 +297,8 @@ class Treequel::Directory
|
|
269
297
|
### Given a Treequel::Branch object, find its corresponding LDAP::Entry and return
|
270
298
|
### it with its operational attributes (http://tools.ietf.org/html/rfc4512#section-3.4)
|
271
299
|
### included.
|
300
|
+
###
|
301
|
+
### @param [Treequel::Branch] branch the branch to look up
|
272
302
|
def get_extended_entry( branch )
|
273
303
|
self.log.debug "Looking up entry (with operational attributes) for %p" % [ branch.dn ]
|
274
304
|
return self.conn.search_ext2( branch.dn, SCOPE[:base], '(objectClass=*)', %w[* +] ).first
|
@@ -289,47 +319,96 @@ class Treequel::Directory
|
|
289
319
|
end
|
290
320
|
|
291
321
|
|
292
|
-
### Perform a +scope+ search at +base+ using the specified +filter+.
|
293
|
-
###
|
294
|
-
### of the
|
295
|
-
|
322
|
+
### Perform a +scope+ search at +base+ using the specified +filter+.
|
323
|
+
###
|
324
|
+
### @param [String, #dn] base The base DN of the search.
|
325
|
+
### @param [Symbol] scope The scope to use in the search; can be one of
|
326
|
+
### +:onelevel+, +:base+, or +:subtree+.
|
327
|
+
### @param [#to_s] filter The search filter (RFC4515), either as a String
|
328
|
+
### or something that stringifies to an filter string.
|
329
|
+
### @param [Hash] options Search options.
|
330
|
+
###
|
331
|
+
### @option options [Class] :results_class (Treequel::Branch)
|
332
|
+
### The Class to use when wrapping results; if not specified, defaults to the class
|
333
|
+
### of +base+ if it responds to #new_from_entry, or Treequel::Branch
|
334
|
+
### if it does not.
|
335
|
+
### @option options [Array<String, Symbol>] :selectattrs (['*'])
|
336
|
+
### The attributes to return from the search; defaults to '*', which means to
|
337
|
+
### return all non-operational attributes. Specifying '+' will cause the search
|
338
|
+
### to include operational parameters as well.
|
339
|
+
### @option options [Boolean] :attrsonly (false)
|
340
|
+
### If +true, the LDAP::Entry objects returned from the search won't have attribute values.
|
341
|
+
### This has no real effect on Treequel::Branches, but is provided in case other
|
342
|
+
### +results_class+ classes need it.
|
343
|
+
### @option options [Array<LDAP::Control>] :server_controls (nil)
|
344
|
+
### Any server controls that should be sent with the search.
|
345
|
+
### @option options [Array<LDAP::Control>] :client_controls (nil)
|
346
|
+
### Any client controls that should be applied to the search.
|
347
|
+
### @option options [Fixnum] :timeout_s (0)
|
348
|
+
### The number of seconds (in addition to :timeout_us) after which the search request should
|
349
|
+
### be aborted.
|
350
|
+
### @option options [Fixnum] :timeout_us (0)
|
351
|
+
### The number of microseconds (in addition to :timeout_s) after which the search request
|
352
|
+
### should be aborted.
|
353
|
+
### @option options [Fixnum] :limit
|
354
|
+
### The maximum number of results to return from the server.
|
355
|
+
### @option options [Array<String>] :sort_attribute
|
356
|
+
### An Array of String attribute names to sort by.
|
357
|
+
### @option options [Proc] :sort_func
|
358
|
+
### A function that will provide sorting.
|
359
|
+
###
|
360
|
+
### @return [Array] the array of results, each of which is wrapped in the
|
361
|
+
### options[:results_class]. If a block is given, it acts like a filter:
|
362
|
+
### the return vaule from the block is returned instead.
|
363
|
+
###
|
364
|
+
### @yield [branch] an optional block, which will receive the results one at a time
|
365
|
+
### @yieldparam [Treequel::Branch] branch the resulting entry, wrapped in
|
366
|
+
### the options[:results_class].
|
367
|
+
def search( base, scope=:subtree, filter='(objectClass=*)', options={} )
|
296
368
|
collectclass = nil
|
297
369
|
|
298
370
|
# If the base argument is an object whose class knows how to create instances of itself
|
299
371
|
# from an LDAP::Entry, use it instead of Treequel::Branch to wrap results
|
300
|
-
if
|
301
|
-
collectclass =
|
372
|
+
if options.key?( :results_class )
|
373
|
+
collectclass = options.delete( :results_class )
|
302
374
|
else
|
303
375
|
collectclass = base.class.respond_to?( :new_from_entry ) ? base.class : Treequel::Branch
|
304
376
|
end
|
305
377
|
|
306
378
|
# Format the arguments in the way #search_ext2 expects them
|
307
|
-
|
308
|
-
self.normalize_search_parameters( base, scope, filter,
|
379
|
+
base_dn, scope, filter, searchopts =
|
380
|
+
self.normalize_search_parameters( base, scope, filter, options )
|
309
381
|
|
310
|
-
# Unwrap the search
|
382
|
+
# Unwrap the search options from the hash in the correct order
|
311
383
|
self.log.debug {
|
312
384
|
attrlist = SEARCH_PARAMETER_ORDER.inject([]) do |list, param|
|
313
|
-
list << "%s: %p" % [ param,
|
385
|
+
list << "%s: %p" % [ param, searchopts[param] ]
|
314
386
|
end
|
315
387
|
"searching with base: %p, scope: %p, filter: %p, %s" %
|
316
|
-
[
|
388
|
+
[ base_dn, scope, filter, attrlist.join(', ') ]
|
317
389
|
}
|
318
|
-
parameters =
|
390
|
+
parameters = searchopts.values_at( *SEARCH_PARAMETER_ORDER )
|
319
391
|
|
320
392
|
# Wrap each result in the class derived from the 'base' argument
|
321
393
|
self.log.debug "Searching via search_ext2 with arguments: %p" % [[
|
322
|
-
|
394
|
+
base_dn, scope, filter, *parameters
|
323
395
|
]]
|
324
|
-
|
325
|
-
|
326
|
-
|
396
|
+
|
397
|
+
results = []
|
398
|
+
|
399
|
+
self.conn.search_ext2( base_dn, scope, filter, *parameters ).each do |entry|
|
400
|
+
branch = collectclass.new_from_entry( entry, self )
|
401
|
+
branch.include_operational_attrs = base.include_operational_attrs? if
|
402
|
+
base.respond_to?( :include_operational_attrs? )
|
403
|
+
|
404
|
+
if block_given?
|
405
|
+
results << yield( branch )
|
406
|
+
else
|
407
|
+
results << branch
|
327
408
|
end
|
328
|
-
else
|
329
|
-
return self.conn.search_ext2( base, scope, filter, *parameters ).
|
330
|
-
collect {|entry| collectclass.new_from_entry(entry, self) }
|
331
409
|
end
|
332
410
|
|
411
|
+
return results
|
333
412
|
rescue RuntimeError => err
|
334
413
|
conn = self.conn
|
335
414
|
|
@@ -347,9 +426,14 @@ class Treequel::Directory
|
|
347
426
|
### Modify the entry specified by the given +dn+ with the specified +mods+, which can be
|
348
427
|
### either an Array of LDAP::Mod objects or a Hash of attribute/value pairs.
|
349
428
|
def modify( branch, mods )
|
350
|
-
|
351
|
-
|
352
|
-
|
429
|
+
if mods.first.respond_to?( :mod_op )
|
430
|
+
self.log.debug "Modifying %s with LDAP mod objects: %p" % [ branch.dn, mods ]
|
431
|
+
self.conn.modify( branch.dn, mods )
|
432
|
+
else
|
433
|
+
normattrs = self.normalize_attributes( mods )
|
434
|
+
self.log.debug "Modifying %s with: %p" % [ branch.dn, normattrs ]
|
435
|
+
self.conn.modify( branch.dn, normattrs )
|
436
|
+
end
|
353
437
|
end
|
354
438
|
|
355
439
|
|
@@ -368,7 +452,7 @@ class Treequel::Directory
|
|
368
452
|
# Merge RDN attributes with existing ones, combining any that exist in both
|
369
453
|
self.log.debug "Smushing rdn attributes %p into %p" % [ branch.rdn_attributes, newdn ]
|
370
454
|
newattrs.merge!( branch.rdn_attributes ) do |key, *values|
|
371
|
-
values.flatten
|
455
|
+
values.flatten.uniq
|
372
456
|
end
|
373
457
|
|
374
458
|
normattrs = self.normalize_attributes( newattrs )
|
@@ -421,6 +505,25 @@ class Treequel::Directory
|
|
421
505
|
end
|
422
506
|
|
423
507
|
|
508
|
+
### Register the specified +modules+
|
509
|
+
def register_controls( *modules )
|
510
|
+
dse = self.conn.root_dse.first
|
511
|
+
supported_controls = dse['supportedControl']
|
512
|
+
|
513
|
+
modules.each do |mod|
|
514
|
+
oid = mod.const_get( :OID ) if mod.const_defined?( :OID )
|
515
|
+
raise NotImplementedError, "%s doesn't define an OID" % [ mod.name ] if oid.nil?
|
516
|
+
|
517
|
+
if supported_controls.include?( oid )
|
518
|
+
@registered_controls << mod
|
519
|
+
else
|
520
|
+
raise Treequel::UnsupportedControl,
|
521
|
+
"%s is not supported by %s" % [ mod.name, self.uri ]
|
522
|
+
end
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
|
424
527
|
### Map the specified +value+ to its Ruby datatype if one is registered for the given
|
425
528
|
### syntax +oid+. If there is no conversion registered, just return the +value+ as-is.
|
426
529
|
def convert_syntax_value( oid, value )
|
@@ -435,6 +538,50 @@ class Treequel::Directory
|
|
435
538
|
end
|
436
539
|
|
437
540
|
|
541
|
+
### Return an Array of Symbols for the controls supported by the Directory, as listed
|
542
|
+
### in the directory's root DSE. Any controls which aren't known (i.e., don't have an
|
543
|
+
### entry in Treequel::Constants::CONTROL_NAMES), the numeric OID will be returned as-is.
|
544
|
+
def supported_controls
|
545
|
+
return self.supported_control_oids.collect {|oid| CONTROL_NAMES[oid] || oid }
|
546
|
+
end
|
547
|
+
|
548
|
+
|
549
|
+
### Return an Array of OID strings representing the controls supported by the Directory,
|
550
|
+
### as listed in the directory's root DSE.
|
551
|
+
def supported_control_oids
|
552
|
+
return self.conn.root_dse.first['supportedControl']
|
553
|
+
end
|
554
|
+
|
555
|
+
|
556
|
+
### Return an Array of Symbols for the extensions supported by the Directory, as listed
|
557
|
+
### in the directory's root DSE. Any extensions which aren't known (i.e., don't have an
|
558
|
+
### entry in Treequel::Constants::EXTENSION_NAMES), the numeric OID will be returned as-is.
|
559
|
+
def supported_extensions
|
560
|
+
return self.supported_extension_oids.collect {|oid| EXTENSION_NAMES[oid] || oid }
|
561
|
+
end
|
562
|
+
|
563
|
+
|
564
|
+
### Return an Array of OID strings representing the extensions supported by the Directory,
|
565
|
+
### as listed in the directory's root DSE.
|
566
|
+
def supported_extension_oids
|
567
|
+
return self.conn.root_dse.first['supportedExtension']
|
568
|
+
end
|
569
|
+
|
570
|
+
|
571
|
+
### Return an Array of Symbols for the features supported by the Directory, as listed
|
572
|
+
### in the directory's root DSE. Any features which aren't known (i.e., don't have an
|
573
|
+
### entry in Treequel::Constants::FEATURE_NAMES), the numeric OID will be returned as-is.
|
574
|
+
def supported_features
|
575
|
+
return self.supported_feature_oids.collect {|oid| FEATURE_NAMES[oid] || oid }
|
576
|
+
end
|
577
|
+
|
578
|
+
|
579
|
+
### Return an Array of OID strings representing the features supported by the Directory,
|
580
|
+
### as listed in the directory's root DSE.
|
581
|
+
def supported_feature_oids
|
582
|
+
return self.conn.root_dse.first['supportedFeatures']
|
583
|
+
end
|
584
|
+
|
438
585
|
|
439
586
|
#########
|
440
587
|
protected
|
@@ -457,10 +604,10 @@ class Treequel::Directory
|
|
457
604
|
conn = LDAP::SSLConn.new( @host, @port, true )
|
458
605
|
when :ssl
|
459
606
|
self.log.debug "Connecting using SSL to %s:%d" % [ @host, @port ]
|
460
|
-
conn = LDAP::SSLConn.new( host, port )
|
607
|
+
conn = LDAP::SSLConn.new( @host, @port )
|
461
608
|
else
|
462
609
|
self.log.debug "Connecting using an unencrypted connection to %s:%d" % [ @host, @port ]
|
463
|
-
conn = LDAP::Conn.new( host, port )
|
610
|
+
conn = LDAP::Conn.new( @host, @port )
|
464
611
|
end
|
465
612
|
|
466
613
|
conn.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 )
|