ldapmapper 1.3 → 1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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==#
|