ldapmapper 1.3 → 1.4
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.
- data/lib/ldapmapper.rb +359 -172
- metadata +1 -1
data/lib/ldapmapper.rb
CHANGED
@@ -1,10 +1,30 @@
|
|
1
1
|
#!/Usr/bin/env ruby
|
2
2
|
#
|
3
|
-
#
|
3
|
+
#
|
4
|
+
# == Synopsis
|
5
|
+
#
|
6
|
+
# LdapMapper : LDAP CRUD Object
|
7
|
+
#
|
8
|
+
# == Usage
|
9
|
+
#
|
10
|
+
# ./ldapmapper.rb [-u|--usage] : usage of the library CLI mode
|
11
|
+
# ./ldapmapper.rb [-h|--help] : Help for this library, man page
|
12
|
+
# ./ldapmapper.rb [-V|--version] : version display for this library
|
13
|
+
# ./ldapmapper.rb [-t|--tests --dn|-d < a dn > [--rootdn|-r <user>]
|
14
|
+
# [--passdn|p <password> ] [-v|--verbose] ]
|
15
|
+
# -> run test mode of the library
|
16
|
+
#
|
17
|
+
# == Date
|
18
|
+
#
|
19
|
+
# 2007-11-05
|
20
|
+
#
|
21
|
+
# == file
|
22
|
+
#
|
23
|
+
# ldapmapper.rb
|
4
24
|
#
|
5
25
|
# == Copyright Ultragreen (c) 2005-2007
|
6
26
|
#
|
7
|
-
# * Version : 1.
|
27
|
+
# * Version : 1.4
|
8
28
|
#
|
9
29
|
# == About :
|
10
30
|
#
|
@@ -15,12 +35,11 @@
|
|
15
35
|
# == Source :
|
16
36
|
#
|
17
37
|
# * http://www.ultragreen.net
|
18
|
-
# *
|
38
|
+
# * Project : http://www.ultragreen.net/projects/show/27
|
19
39
|
# * Wiki : http://www.ultragreen.net/wiki/27
|
20
40
|
# * Downloads : http://www.ultragreen.net/projects/list_files/27
|
21
41
|
# * Forum : http://www.ultragreen.net/projects/27/boards
|
22
42
|
#
|
23
|
-
#
|
24
43
|
# == Exemples :
|
25
44
|
#
|
26
45
|
# #!/usr/local/bin/ruby
|
@@ -90,7 +109,7 @@
|
|
90
109
|
# * objectClass =
|
91
110
|
# - top
|
92
111
|
# - organizationalUnit
|
93
|
-
# * dn = ou=toto,dc=
|
112
|
+
# * dn = ou=toto,dc=__domain__,dc=__tld__
|
94
113
|
# Jeu 7 sep 2006 16:11:44 CEST
|
95
114
|
|
96
115
|
|
@@ -98,25 +117,86 @@
|
|
98
117
|
require 'ldap'
|
99
118
|
require "ldap/schema"
|
100
119
|
|
120
|
+
def output(_string)
|
121
|
+
puts _string
|
122
|
+
end
|
123
|
+
|
124
|
+
# Set debug default to 0
|
125
|
+
$verbose = 0
|
101
126
|
|
102
127
|
# General module for LDAP CRUD Ojects
|
103
128
|
module Ldapmapper
|
104
|
-
|
129
|
+
|
105
130
|
# identity lib
|
131
|
+
# Library name
|
132
|
+
LIB_NAME = "Ldapmapper"
|
106
133
|
# version of the library
|
107
|
-
LIB_VERSION='1.
|
134
|
+
LIB_VERSION='1.4'
|
108
135
|
# name of the author
|
109
136
|
AUTHOR='Romain GEORGES'
|
110
137
|
# date of creation
|
111
138
|
DATE='30/07/2005'
|
112
139
|
# valuable observations
|
113
140
|
OBS='Generic LDAP class'
|
114
|
-
|
141
|
+
|
142
|
+
# Module method for version display
|
143
|
+
def version
|
144
|
+
output "#{LIB_NAME} : file => #{File::basename(__FILE__)}:"
|
145
|
+
output 'this is a RUBY library file'
|
146
|
+
output "Copyright (c) Ultragreen Software"
|
147
|
+
output "Version : #{LIB_VERSION}"
|
148
|
+
output "Author : #{AUTHOR}"
|
149
|
+
output "Date release : #{DATE}"
|
150
|
+
output "Observation : #{OBS}"
|
151
|
+
end
|
152
|
+
|
153
|
+
# Module method for version display
|
154
|
+
def tests(_dn,_rootdn,_passdn)
|
155
|
+
output "Running tests on #{_dn}"
|
156
|
+
_dn = "ou=toto,#{_dn}"
|
157
|
+
output "test on ou=toto in node : #{_dn}"
|
158
|
+
record = LdapMapper.new(_dn,_rootdn,_passdn)
|
159
|
+
output "- Could create it ? : #{record.can_create?}"
|
160
|
+
output "- Already exist ? : #{record.exist?}"
|
161
|
+
output "- Is it a node ? : #{record.is_node?}"
|
162
|
+
output "- Is it the base ? : #{record.is_base?}"
|
163
|
+
if record.can_create?
|
164
|
+
output "- Create ou=toto in node : #{_dn}"
|
165
|
+
record.add_objectclass!('organizationalUnit')
|
166
|
+
record.ou = 'toto'
|
167
|
+
record.description = "Test"
|
168
|
+
output "- Is it valid ? : #{record.valid?}"
|
169
|
+
record.commit!
|
170
|
+
end
|
171
|
+
if record.exist? then
|
172
|
+
output "- ObjectClasses list :"
|
173
|
+
record.list_objectclass.each{|objectclass|
|
174
|
+
output " * #{objectclass}"
|
175
|
+
}
|
176
|
+
output "- Attributes list : "
|
177
|
+
record.list_attributs.each{|attribute,value|
|
178
|
+
if value.size > 1 then
|
179
|
+
output "* #{attribute} ="
|
180
|
+
value.each{|val| puts " - #{val}"
|
181
|
+
}
|
182
|
+
else
|
183
|
+
output "* #{attribute} = #{value}"
|
184
|
+
end
|
185
|
+
}
|
186
|
+
record.description = `date`
|
187
|
+
record.commit!
|
188
|
+
# output "deleting ou=toto..."
|
189
|
+
# record.delete!
|
190
|
+
output ">> test done."
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
115
195
|
# generic class for LDAP object
|
116
196
|
class LdapTemplate
|
117
|
-
|
197
|
+
|
118
198
|
# attributs for LDAP connection
|
119
|
-
|
199
|
+
|
120
200
|
# hostname of the LDAP server
|
121
201
|
attr_accessor :host_ldap
|
122
202
|
# TCP/IP port of the LDAP server
|
@@ -131,25 +211,27 @@ module Ldapmapper
|
|
131
211
|
attr_accessor :passdn_ldap
|
132
212
|
# LDAP rootdn for LDAP
|
133
213
|
attr_accessor :rootdn_ldap
|
134
|
-
|
214
|
+
|
135
215
|
# constructor for LdapTemplate
|
136
216
|
#
|
137
217
|
# _passdn is required, _rootdn, _host, _filter, _port and _scope are optionals
|
138
218
|
#
|
139
219
|
# return a boolean
|
140
|
-
def initialize(
|
220
|
+
def initialize(_host='localhost', _port=389, _rootdn='', _passdn='', _filter='(objectClass=*)', _scope=LDAP::LDAP_SCOPE_SUBTREE )
|
141
221
|
@host_ldap = _host # default localhost
|
142
222
|
@port_ldap = _port # default 389
|
143
223
|
@scope_ldap = _scope # default to SUBTREE
|
144
224
|
@filter_ldap = _filter # default (objectClass=*)
|
145
|
-
@basedn_ldap = get_basedn(_host,_port)
|
146
|
-
@passdn_ldap = _passdn #
|
147
|
-
@rootdn_ldap = _rootdn # default
|
225
|
+
@basedn_ldap = get_basedn(_host,_port,_rootdn,_passdn)
|
226
|
+
@passdn_ldap = _passdn # default empty
|
227
|
+
@rootdn_ldap = _rootdn # default empty
|
148
228
|
return true
|
149
229
|
end
|
150
|
-
|
230
|
+
|
231
|
+
|
232
|
+
|
151
233
|
end
|
152
|
-
|
234
|
+
|
153
235
|
# Mapping LDAP object class
|
154
236
|
#
|
155
237
|
# This is the real CRUD Class
|
@@ -158,7 +240,7 @@ module Ldapmapper
|
|
158
240
|
#
|
159
241
|
# _dn and _passdn are required, _rootdn, _host and _port are optionals
|
160
242
|
class LdapMapper < LdapTemplate
|
161
|
-
|
243
|
+
|
162
244
|
# DN binding point attribut
|
163
245
|
attr_accessor :dn_ldap
|
164
246
|
# Hash of attributes with optional or mandatory aspects in value
|
@@ -167,44 +249,47 @@ module Ldapmapper
|
|
167
249
|
attr_accessor :list_objectclass
|
168
250
|
# Hash of attributes in LDIF mapping, value should be an array in case of multivalue data
|
169
251
|
attr_accessor :list_attributs
|
170
|
-
|
252
|
+
attr_accessor :list_attributs_rollback
|
253
|
+
|
171
254
|
# constructor with dn_ldap initialisation
|
172
255
|
#
|
173
256
|
# _dn and _passdn are required, _rootdn, _host and _port are optionals
|
174
257
|
#
|
175
258
|
# return a boolean
|
176
|
-
def initialize(_dn,
|
259
|
+
def initialize(_dn, _rootdn='', _passdn='', _host = 'localhost', _port = 389)
|
177
260
|
_scope = LDAP::LDAP_SCOPE_SUBTREE
|
178
261
|
_filter = '(objectClass=*)'
|
179
|
-
super(
|
262
|
+
super( _host, _port, _rootdn, _passdn, _filter, _scope )
|
180
263
|
@dn_ldap = _dn
|
181
264
|
@list_objectclass = Array::new
|
182
265
|
@list_attributs_type = Hash::new
|
183
266
|
@list_attributs = Hash::new
|
184
267
|
add_objectclass!
|
268
|
+
@list_attributs_rollback = @list_attributs
|
185
269
|
end
|
186
|
-
|
270
|
+
|
271
|
+
|
272
|
+
|
187
273
|
# add an objectclass in the list and map attribut
|
188
274
|
#
|
189
275
|
# _objectclass is optional
|
190
276
|
#
|
191
277
|
# return an Hash
|
192
278
|
def add_objectclass!(_objectclass = 'top')
|
193
|
-
@list_objectclass = @list_objectclass.concat(get_objectclass_list(self.dn_ldap,self.host_ldap,self.port_ldap))
|
279
|
+
@list_objectclass = @list_objectclass.concat(get_objectclass_list(self.dn_ldap, self.host_ldap, self.port_ldap, self.rootdn_ldap, self.passdn_ldap))
|
194
280
|
@list_objectclass.push(_objectclass).uniq!
|
195
|
-
@list_attributs_type = get_attributs_list(self.list_objectclass,self.host_ldap,self.port_ldap)
|
196
|
-
|
197
|
-
@list_attributs = map_record(self.dn_ldap,self.host_ldap,self.port_ldap)
|
281
|
+
@list_attributs_type = get_attributs_list(self.list_objectclass, self.host_ldap, self.port_ldap, self.rootdn_ldap, self.passdn_ldap)
|
282
|
+
@list_attributs = map_record(self.dn_ldap, self.host_ldap, self.port_ldap, self.rootdn_ldap, self.passdn_ldap)
|
198
283
|
if not @list_attributs.nil? or @list_attributs.empty? then
|
199
284
|
@list_attributs.each{|_key,_value|
|
200
285
|
@list_attributs_type.each{|_attr,_trash|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
286
|
+
@list_prov = get_alias(_key,self.host_ldap, self.port_ldap, self.rootdn_ldap, self.passdn_ldap)
|
287
|
+
if @list_prov then
|
288
|
+
if @list_prov.include?(_attr) then
|
289
|
+
@list_attributs.delete(_key)
|
290
|
+
@list_attributs[_attr] = _value
|
291
|
+
end
|
292
|
+
end
|
208
293
|
}
|
209
294
|
}
|
210
295
|
end
|
@@ -217,52 +302,59 @@ module Ldapmapper
|
|
217
302
|
def #{_key.downcase}=(_value)
|
218
303
|
@list_attributs['#{_key}'] = _value
|
219
304
|
end
|
220
|
-
|
305
|
+
")
|
221
306
|
}
|
222
307
|
end
|
223
|
-
|
308
|
+
|
224
309
|
# existance of an LDAP instance test method
|
225
310
|
#
|
226
311
|
# return a boolean
|
227
312
|
def exist?
|
228
|
-
if list_arbitrary_node(self.dn_ldap,self.host_ldap,self.port_ldap).empty? then
|
313
|
+
if list_arbitrary_node(self.dn_ldap, self.host_ldap, self.port_ldap, self.rootdn_ldap, self.passdn_ldap).empty? then
|
229
314
|
return false
|
230
315
|
else
|
231
316
|
return true
|
232
317
|
end
|
233
318
|
end
|
234
|
-
|
319
|
+
|
320
|
+
# rollback to beggining of transaction
|
321
|
+
#
|
322
|
+
# return a boolean
|
323
|
+
def rollback!
|
324
|
+
@list_attributs = @list_attributs_rollback
|
325
|
+
end
|
326
|
+
|
235
327
|
# test methode for LDAP instance situation node or termination
|
236
328
|
#
|
237
329
|
# return a boolean
|
238
330
|
def is_node?
|
239
|
-
if list_arbitrary_node(self.dn_ldap,self.host_ldap,self.port_ldap).length > 1 then
|
240
|
-
|
331
|
+
if list_arbitrary_node(self.dn_ldap, self.host_ldap, self.port_ldap, self.rootdn_ldap, self.passdn_ldap).length > 1 then
|
332
|
+
return true
|
241
333
|
else
|
242
|
-
|
334
|
+
return false
|
243
335
|
end
|
244
336
|
end
|
245
|
-
|
337
|
+
|
246
338
|
# test methode to check the ability to create the instance, already exist or not bindable
|
247
339
|
#
|
248
340
|
# return a boolean
|
249
341
|
def can_create?
|
250
342
|
return false if self.is_base?
|
251
|
-
if list_arbitrary_node(self.get_previous,self.host_ldap,self.port_ldap).length >= 1 and not self.exist? then
|
252
|
-
|
343
|
+
if list_arbitrary_node(self.get_previous,self.host_ldap,self.port_ldap, self.rootdn_ldap, self.passdn_ldap).length >= 1 and not self.exist? then
|
344
|
+
return true
|
253
345
|
else
|
254
|
-
|
346
|
+
return false
|
255
347
|
end
|
256
348
|
end
|
257
|
-
|
349
|
+
|
258
350
|
# return true if the dn to search is the basedn of the tree
|
259
351
|
#
|
260
352
|
# return a boolean
|
261
353
|
def is_base?
|
262
354
|
if self.dn_ldap == self.basedn_ldap then
|
263
|
-
|
355
|
+
return true
|
264
356
|
else
|
265
|
-
|
357
|
+
return false
|
266
358
|
end
|
267
359
|
end
|
268
360
|
|
@@ -272,7 +364,7 @@ module Ldapmapper
|
|
272
364
|
def must
|
273
365
|
_must_list = Array::new
|
274
366
|
self.list_attributs_type.each{|_key,_value|
|
275
|
-
|
367
|
+
_must_list.push(_key) if _value == 'MUST'
|
276
368
|
}
|
277
369
|
_must_list.delete('dn') if _must_list.include?('dn')
|
278
370
|
return _must_list
|
@@ -295,7 +387,7 @@ module Ldapmapper
|
|
295
387
|
def valid?
|
296
388
|
_result = true
|
297
389
|
self.must.each{|attribute|
|
298
|
-
|
390
|
+
_result = false if not self.list_attributs.include?(attribute)
|
299
391
|
}
|
300
392
|
return _result
|
301
393
|
end
|
@@ -306,62 +398,99 @@ module Ldapmapper
|
|
306
398
|
def get_previous
|
307
399
|
_rec_res = String::new('')
|
308
400
|
if not self.is_base? then
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
401
|
+
_rdn = String::new('')
|
402
|
+
_dn_table = Array::new
|
403
|
+
_rdn,*_dn_table = self.dn_ldap.split(',')
|
404
|
+
_rec_res = _dn_table.join(',')
|
313
405
|
end
|
314
406
|
return _rec_res
|
315
407
|
end
|
316
|
-
|
408
|
+
|
317
409
|
# method to list dn after the node in the the LDAP tree for the first level,
|
318
410
|
#
|
319
411
|
# return an Array
|
320
412
|
def list_node
|
321
413
|
_my_res = Array::new
|
322
|
-
_my_res = list_arbitrary_node(self.dn_ldap,self.host_ldap,self.port_ldap,LDAP::LDAP_SCOPE_ONELEVEL)
|
414
|
+
_my_res = list_arbitrary_node(self.dn_ldap,self.host_ldap,self.port_ldap, self.rootdn_ldap, self.passdn_ldap, LDAP::LDAP_SCOPE_ONELEVEL)
|
323
415
|
_my_res.delete(self.dn_ldap) if _my_res.include?(self.dn_ldap)
|
324
416
|
return _my_res
|
325
417
|
end
|
326
418
|
|
419
|
+
# delete the dn object in LDAP server
|
420
|
+
#
|
421
|
+
# return a boolean
|
422
|
+
def delete!
|
423
|
+
if self.exist? and not self.is_node? then
|
424
|
+
return delete_object(self.dn_ldap, self.host_ldap, self.port_ldap, self.rootdn_ldap, self.passdn_ldap)
|
425
|
+
else
|
426
|
+
return false
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
327
430
|
# commit the modification or the adding of the object in LDAP server
|
328
431
|
#
|
329
432
|
# return a boolean
|
330
433
|
def commit!
|
331
434
|
if self.exist? and self.valid? then
|
332
|
-
|
333
|
-
|
334
|
-
return true
|
435
|
+
# case modifying an LDAP object
|
436
|
+
return mod_object(self.dn_ldap, self.list_attributs.merge(self.list_attributs_rollback), self.host_ldap, self.port_ldap, self.rootdn_ldap, self.passdn_ldap)
|
335
437
|
elsif self.can_create? and self.valid? then
|
336
|
-
|
337
|
-
|
338
|
-
return true
|
438
|
+
# case creating new object
|
439
|
+
return add_object(self.dn_ldap, self.list_attributs, self.host_ldap, self.port_ldap, self.rootdn_ldap, self.passdn_ldap)
|
339
440
|
else
|
340
|
-
|
341
|
-
|
441
|
+
return false
|
442
|
+
# case can't commit
|
342
443
|
end
|
343
444
|
end
|
344
|
-
|
445
|
+
|
446
|
+
end
|
447
|
+
|
448
|
+
|
449
|
+
|
450
|
+
|
451
|
+
|
452
|
+
# global connector for LDAP instanciate at the first request
|
453
|
+
#
|
454
|
+
# _host, _port, _rootdn and _passdn are optional
|
455
|
+
#
|
456
|
+
# return a global connecter handler
|
457
|
+
def connector(_host='localhost', _port=389, _rootdn='', _passdn='')
|
458
|
+
begin
|
459
|
+
if not $connection then
|
460
|
+
output "connecting to #{_host} on port : #{_port}" if $verbose
|
461
|
+
$connection = LDAP::Conn.new(_host,_port)
|
462
|
+
$connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
|
463
|
+
end
|
464
|
+
if _rootdn.empty? and not $bind then
|
465
|
+
output 'Anonymous binding' if $verbose
|
466
|
+
$connection = $connection.bind
|
467
|
+
$bind = true
|
468
|
+
elsif not _rootdn.empty? and not $authenticated then
|
469
|
+
output 'Authenticated binding' if $verbose
|
470
|
+
$connection.unbind if $connection.bound?
|
471
|
+
$connection = $connection.bind("#{_rootdn}", "#{_passdn}")
|
472
|
+
$authenticated = true
|
473
|
+
end
|
474
|
+
return $connection
|
475
|
+
rescue Exception
|
476
|
+
raise LdapmapperConnectionError
|
477
|
+
end
|
345
478
|
end
|
346
|
-
|
347
|
-
|
479
|
+
|
348
480
|
# global method that list objectclass for a speficique dn
|
349
481
|
#
|
350
482
|
# server free methode
|
351
483
|
#
|
352
|
-
# _dn is required, _host, _port, _scope and _filter are optionals
|
484
|
+
# _dn is required, _host, _port, _rootdn, _passdn, _scope and _filter are optionals
|
353
485
|
#
|
354
486
|
# return an Array
|
355
|
-
def get_objectclass_list(_dn,_host='localhost',_port=389,_scope=LDAP::LDAP_SCOPE_BASE,_filter='(objectClass=*)')
|
487
|
+
def get_objectclass_list(_dn,_host='localhost',_port=389,_rootdn='',_passdn='',_scope=LDAP::LDAP_SCOPE_BASE,_filter='(objectClass=*)')
|
356
488
|
_table_res = Array::new
|
357
489
|
begin
|
358
|
-
|
359
|
-
|
360
|
-
_conn.bind {
|
361
|
-
_conn.search(_dn,_scope,_filter){|_e|
|
362
|
-
_table_res = _e.to_hash()['objectClass']
|
363
|
-
}
|
490
|
+
connector(_host, _port, _rootdn, _passdn).search(_dn,_scope,_filter){|_e|
|
491
|
+
_table_res = _e.to_hash()['objectClass']
|
364
492
|
}
|
493
|
+
rescue
|
365
494
|
ensure
|
366
495
|
return _table_res
|
367
496
|
end
|
@@ -369,17 +498,15 @@ module Ldapmapper
|
|
369
498
|
|
370
499
|
# get the base dn of an LDAP tree
|
371
500
|
#
|
372
|
-
# _host and
|
501
|
+
# _host, _port, _rootdn and _passdn are optionals
|
373
502
|
#
|
374
503
|
# return a String
|
375
|
-
def get_basedn(_host='localhost',_port=389)
|
504
|
+
def get_basedn(_host='localhost',_port=389,_rootdn='',_passdn='')
|
376
505
|
_my_basedn = String::new('')
|
377
506
|
begin
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
_my_basedn = _conn.root_dse[0]["namingContexts"].to_s
|
382
|
-
}
|
507
|
+
_my_basedn = connector(_host,_port,_rootdn,_passdn).root_dse[0]["namingContexts"].to_s
|
508
|
+
rescue
|
509
|
+
raise LdapmapperGetBaseDnError
|
383
510
|
ensure
|
384
511
|
return _my_basedn
|
385
512
|
end
|
@@ -390,15 +517,13 @@ module Ldapmapper
|
|
390
517
|
# _attribute is required, _host and _port are optionals
|
391
518
|
#
|
392
519
|
# return an Array
|
393
|
-
def get_alias(_attribute,_host='localhost',_port=389)
|
520
|
+
def get_alias(_attribute,_host='localhost',_port=389,_rootdn='',_passdn='')
|
394
521
|
_my_list_attributs = Array::new
|
395
522
|
begin
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
}
|
401
|
-
|
523
|
+
_schema = connector(_host,_port,_rootdn,_passdn).schema()
|
524
|
+
_my_list_attributs = _schema.alias(_attribute)
|
525
|
+
rescue
|
526
|
+
raise LdapmapperGetAttributAliasError
|
402
527
|
ensure
|
403
528
|
return _my_list_attributs
|
404
529
|
end
|
@@ -408,133 +533,195 @@ module Ldapmapper
|
|
408
533
|
#
|
409
534
|
# server free methode
|
410
535
|
#
|
411
|
-
# _dn id required, _host, _port, _scope, _filter are optionals
|
536
|
+
# _dn id required, _host, _port, _rootdn, _passdn, _scope, _filter are optionals
|
412
537
|
#
|
413
538
|
# return an Array
|
414
|
-
def list_arbitrary_node(_dn,_host=localhost,_port=389,_scope=LDAP::LDAP_SCOPE_SUBTREE,_filter='(objectClass=*)')
|
539
|
+
def list_arbitrary_node(_dn,_host=localhost,_port=389,_rootdn='',_passdn='',_scope=LDAP::LDAP_SCOPE_SUBTREE,_filter='(objectClass=*)')
|
415
540
|
_table_res = Array::new
|
416
541
|
begin
|
417
|
-
|
418
|
-
|
419
|
-
_conn.bind {
|
420
|
-
_conn.search(_dn,_scope,_filter){|_e|
|
421
|
-
_table_res.push(_e.dn)
|
422
|
-
}
|
542
|
+
connector(_host,_port,_rootdn,_passdn).search(_dn,_scope,_filter){|_e|
|
543
|
+
_table_res.push(_e.dn)
|
423
544
|
}
|
545
|
+
rescue
|
546
|
+
raise LdapmapperGetDnsListError
|
424
547
|
ensure
|
425
548
|
return _table_res
|
426
549
|
end
|
427
|
-
|
428
550
|
end
|
429
|
-
|
551
|
+
|
430
552
|
# get the attributs list of an objectclass list
|
431
553
|
#
|
432
554
|
# server free method
|
433
555
|
#
|
434
|
-
# _list_objectclass is required, _host and
|
556
|
+
# _list_objectclass is required, _host, _port, _rootdn and _passdn are optionals
|
435
557
|
#
|
436
558
|
# return an Hash
|
437
|
-
def get_attributs_list(_list_objectclass,_host='localhost',_port=389)
|
559
|
+
def get_attributs_list(_list_objectclass,_host='localhost',_port=389,_rootdn='',_passdn='')
|
438
560
|
_my_list_attributs = Hash::new
|
439
561
|
begin
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
_prov_must.each{|attributs| _my_list_attributs[attributs] = 'MUST'} unless _prov_must.nil? or _prov_must.empty?
|
449
|
-
_prov_may.each{|attributs| _my_list_attributs[attributs] = 'MAY'} unless _prov_may.nil? or _prov_may.empty?
|
450
|
-
end
|
451
|
-
}
|
562
|
+
_schema = connector(_host,_port,_rootdn,_passdn).schema()
|
563
|
+
_list_objectclass.each{|objectclass|
|
564
|
+
if objectclass != 'top' then
|
565
|
+
_prov_must = _schema.must(objectclass)
|
566
|
+
_prov_may = _schema.may(objectclass)
|
567
|
+
_prov_must.each{|attributs| _my_list_attributs[attributs] = 'MUST'} unless _prov_must.nil? or _prov_must.empty?
|
568
|
+
_prov_may.each{|attributs| _my_list_attributs[attributs] = 'MAY'} unless _prov_may.nil? or _prov_may.empty?
|
569
|
+
end
|
452
570
|
}
|
453
|
-
|
571
|
+
rescue
|
572
|
+
raise LdapmapperGetAttributsListError
|
573
|
+
ensure
|
454
574
|
_my_list_attributs["dn"] = "MUST"
|
455
575
|
_my_list_attributs["objectClass"] = "MUST"
|
456
|
-
return _my_list_attributs
|
457
|
-
|
458
|
-
end
|
576
|
+
return _my_list_attributs
|
577
|
+
end
|
459
578
|
end
|
460
|
-
|
579
|
+
|
461
580
|
# map the attributs of class at run time for the current LDAP Object at precise DN
|
462
581
|
#
|
463
|
-
# _dn is required, _host, _port, _scope and _filter are optionals
|
582
|
+
# _dn is required, _host, _port, _rootdn, _passdn, _scope and _filter are optionals
|
464
583
|
#
|
465
584
|
# return an Hash
|
466
|
-
def map_record(_dn,_host='localhost',_port=389,_scope=LDAP::
|
585
|
+
def map_record(_dn,_host='localhost',_port=389,_rootdn='',_passdn='',_scope=LDAP::LDAP_SCOPE_BASE,_filter='(objectClass=*)')
|
586
|
+
_prov_hash = Hash::new
|
467
587
|
begin
|
468
|
-
|
469
|
-
|
470
|
-
_conn.bind {
|
471
|
-
_conn.search(_dn,_scope,_filter){|_e|
|
472
|
-
return _e.to_hash()
|
473
|
-
}
|
588
|
+
connector(_host,_port,_rootdn,_passdn).search(_dn,_scope,_filter){|_e|
|
589
|
+
_prov_hash = _e.to_hash()
|
474
590
|
}
|
475
591
|
rescue
|
476
|
-
|
592
|
+
|
593
|
+
ensure
|
594
|
+
return _prov_hash
|
477
595
|
end
|
478
596
|
end
|
479
|
-
|
597
|
+
|
480
598
|
# add an ldap object
|
481
599
|
#
|
482
|
-
# _dn
|
600
|
+
# _dn and _record are required, _host, _port, _rootdn and _passdn are optional
|
483
601
|
#
|
484
602
|
# return a boolean
|
485
|
-
def add_object(_dn, _record,
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
begin
|
491
|
-
_data = self.list_attributs
|
492
|
-
_data.each{|_key,_value|
|
493
|
-
_data[_key] = _value.to_a
|
494
|
-
}
|
495
|
-
_conn.add("#{_dn}", _data)
|
496
|
-
return true
|
497
|
-
rescue LDAP::ResultError
|
498
|
-
return false
|
499
|
-
end
|
603
|
+
def add_object(_dn, _record, _host='localhost',_port=389, _rootdn='', _passdn='')
|
604
|
+
_record.delete('dn')
|
605
|
+
_data = _record
|
606
|
+
_data.each{|_key,_value|
|
607
|
+
_data[_key] = _value.to_a
|
500
608
|
}
|
609
|
+
begin
|
610
|
+
connector(_host,_port,_rootdn,_passdn).add("#{_dn}", _data)
|
611
|
+
return true
|
612
|
+
rescue LDAP::ResultError
|
613
|
+
raise LdapmapperAddRecordError
|
614
|
+
return false
|
615
|
+
end
|
501
616
|
end
|
502
617
|
|
503
618
|
# modify an ldap object
|
504
619
|
#
|
505
|
-
# _dn
|
620
|
+
# _dn and _record are required, _host, _port, _rootdn and _passdn are optional
|
506
621
|
#
|
507
622
|
# return a boolean
|
508
|
-
def mod_object(_dn,
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
623
|
+
def mod_object(_dn, _mod, _host='localhost',_port=389, _rootdn='', _passdn='')
|
624
|
+
# begin
|
625
|
+
_mod.delete('dn')
|
626
|
+
_data = _mod
|
627
|
+
_data.each{|_key,_value|
|
628
|
+
_data[_key] = _value.to_a
|
629
|
+
}
|
630
|
+
connector(_host,_port,_rootdn,_passdn).modify("#{_dn}", _data)
|
631
|
+
return true
|
632
|
+
# rescue LDAP::ResultError
|
633
|
+
# raise LdapmapperModRecordError
|
634
|
+
# return false
|
635
|
+
# end
|
636
|
+
end
|
637
|
+
|
638
|
+
# delete an ldap object
|
639
|
+
#
|
640
|
+
# _dn is required, _host, _port, _rootdn and _passdn are optional
|
641
|
+
#
|
642
|
+
# return a boolean
|
643
|
+
def delete_object(_dn, _host='localhost',_port=389, _rootdn='', _passdn='')
|
644
|
+
begin
|
645
|
+
connector(_host,_port,_rootdn,_passdn).delete("#{_dn}")
|
646
|
+
return true
|
647
|
+
rescue LDAP::ResultError
|
648
|
+
raise LdapmapperDeleteRecordError
|
649
|
+
return false
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
653
|
+
|
654
|
+
# exceptions definitions for Ldapmapper
|
655
|
+
# raise when a LDAP Cconnection failed of a record failed
|
656
|
+
class LdapmapperConnectionError < Exception; end
|
657
|
+
# raise when an modification of a record failed
|
658
|
+
class LdapmapperModRecordError < Exception; end
|
659
|
+
# raise when an adding of a record failed
|
660
|
+
class LdapmapperAddRecordError < Exception; end
|
661
|
+
# raise when the retrieving of a record failed
|
662
|
+
class LdapmapperGetRecordError < Exception; end
|
663
|
+
# raise when the retrieving of Schema's data failed
|
664
|
+
class LdapmapperGetAttibutAliasError < Exception; end
|
665
|
+
# raise when the browsing of an LDAP tree failed
|
666
|
+
class LdapmapperGetDnsListError < Exception; end
|
667
|
+
# raise when the retrieving of root DSE record failed
|
668
|
+
class LdapmapperGetBaseDnError < Exception; end
|
669
|
+
# raise when the retrieving of Attributs list failed
|
670
|
+
class LdapmapperGetAttributsListError < Exception; end
|
671
|
+
# raise when the retrieving of objectclasses list failed
|
672
|
+
class LdapmapperGetObjectClassListError < Exception; end
|
673
|
+
# raise when the removing of a dn failed
|
674
|
+
class LdapmapperDeleteRecordError < Exception; end
|
675
|
+
end
|
676
|
+
|
677
|
+
# run description of the library in interactive mode
|
678
|
+
if $0 == __FILE__ then
|
679
|
+
require 'getoptlong'
|
680
|
+
require 'rdoc/usage'
|
681
|
+
|
682
|
+
include Ldapmapper
|
683
|
+
|
684
|
+
$command_name = File::basename(__FILE__)
|
685
|
+
$arguments = Hash::new
|
686
|
+
# option catching
|
687
|
+
opts = GetoptLong.new(
|
688
|
+
[ "--help", "-h", GetoptLong::NO_ARGUMENT ],
|
689
|
+
[ "--usage", "-u", GetoptLong::NO_ARGUMENT ],
|
690
|
+
[ "--tests", "-t", GetoptLong::NO_ARGUMENT ],
|
691
|
+
[ "--verbose", "-v", GetoptLong::NO_ARGUMENT ],
|
692
|
+
[ "--passdn", "-p", GetoptLong::REQUIRED_ARGUMENT ],
|
693
|
+
[ "--rootdn", "-r", GetoptLong::REQUIRED_ARGUMENT ],
|
694
|
+
[ "--dn", "-d", GetoptLong::REQUIRED_ARGUMENT ],
|
695
|
+
[ "--version", "-V", GetoptLong::NO_ARGUMENT ]
|
696
|
+
|
697
|
+
)
|
698
|
+
# process the parsed options
|
699
|
+
begin
|
700
|
+
opts.each do |_opt, _arg|
|
701
|
+
$arguments[_opt] = _arg
|
702
|
+
end
|
703
|
+
RDoc::usage('usage') and exit 0 if $arguments.include?("--usage")
|
704
|
+
RDoc::usage and exit 0 if $arguments.include?("--help")
|
705
|
+
version if $arguments.include?("--version")
|
706
|
+
rescue GetoptLong::MissingArgument,GetoptLong::InvalidOption
|
707
|
+
output 'ERROR : Invalid or missing argument'
|
708
|
+
RDoc::usage('usage')
|
709
|
+
exit 1
|
525
710
|
end
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
puts "Date release : #{DATE}"
|
535
|
-
puts "Observation : #{OBS}"
|
711
|
+
if $arguments.include?("--tests") then
|
712
|
+
RDoc::usage('usage') and exit 0 unless $arguments.include?("--dn")
|
713
|
+
$verbose = 1 if $arguments.include?("--verbose")
|
714
|
+
output "Debbugging verbose mode activated." if $verbose
|
715
|
+
_dn = $arguments["--dn"]
|
716
|
+
_passdn = ($arguments.include?("--passdn"))? $arguments["--passdn"] : ''
|
717
|
+
_rootdn = ($arguments.include?("--rootdn"))? $arguments["--rootdn"] : ''
|
718
|
+
tests(_dn,_rootdn,_passdn)
|
536
719
|
end
|
537
|
-
|
720
|
+
|
721
|
+
|
722
|
+
|
538
723
|
end
|
539
724
|
|
725
|
+
|
726
|
+
|
540
727
|
#==END==#
|