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.
Files changed (2) hide show
  1. data/lib/ldapmapper.rb +359 -172
  2. metadata +1 -1
@@ -1,10 +1,30 @@
1
1
  #!/Usr/bin/env ruby
2
2
  #
3
- # = LdapMapper : LDAP CRUD Object
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.3
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
- # * Projetc : http://www.ultragreen.net/projects/show/27
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=ultragreen,dc=net
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.3'
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(_passdn,_rootdn='cn=root',_host='localhost', _filter='(objectClass=*)', _port=389, _scope=LDAP::LDAP_SCOPE_SUBTREE)
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 # no default
147
- @rootdn_ldap = _rootdn # default cn=root
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,_passdn, _rootdn='cn=root',_host = 'localhost', _port = 389)
259
+ def initialize(_dn, _rootdn='', _passdn='', _host = 'localhost', _port = 389)
177
260
  _scope = LDAP::LDAP_SCOPE_SUBTREE
178
261
  _filter = '(objectClass=*)'
179
- super(_passdn, _rootdn, _host, _filter, _port, _scope )
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
- @list_prov = self.get_alias(_key)
202
- if @list_prov then
203
- if self.get_alias(_key).include?(_attr) then
204
- @list_attributs.delete(_key)
205
- @list_attributs[_attr] = _value
206
- end
207
- end
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
- return true
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
- return false
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
- return true
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
- return false
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
- return true
355
+ return true
264
356
  else
265
- return false
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
- _must_list.push(_key) if _value == 'MUST'
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
- _result = false if not self.list_attributs.include?(attribute)
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
- _rdn = String::new('')
310
- _dn_table = Array::new
311
- _rdn,*_dn_table = self.dn_ldap.split(',')
312
- _rec_res = _dn_table.join(',')
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
- # case modifying an LDAP object
333
- mod_object(self.dn_ldap, self.list_attributs, self.rootdn_ldap, self.basedn_ldap, self.passdn_ldap, self.host_ldap, self.port_ldap)
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
- # case creating new object
337
- add_object(self.dn_ldap, self.list_attributs, self.rootdn_ldap, self.basedn_ldap, self.passdn_ldap, self.host_ldap, self.port_ldap)
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
- return false
341
- # case can't commit
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
- _conn = LDAP::Conn.new(_host,_port)
359
- _conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
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 _port are optionals
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
- _conn = LDAP::Conn.new(_host,_port)
379
- _conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
380
- _conn.bind {
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
- _conn = LDAP::Conn.new(_host, _port)
397
- _conn.bind{
398
- _schema = _conn.schema()
399
- _my_list_attributs = _schema.alias(_attribute)
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
- _conn = LDAP::Conn.new(_host,_port)
418
- _conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
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 _port are optionals
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
- _conn = LDAP::Conn.new(_host, _port)
441
- _conn.bind{
442
- _schema = _conn.schema()
443
- _list_objectclass.each{|objectclass|
444
- if objectclass != 'top' then
445
-
446
- _prov_may = _schema.must(objectclass)
447
- _prov_must = _schema.may(objectclass)
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
- ensure
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::LDAP_SCOPE_SUBTREE,_filter='(objectClass=*)')
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
- _conn = LDAP::Conn.new(_host,_port)
469
- _conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
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
- return Hash::new
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, _record, _rootdn, _basedn and _passdn are required, _host and _port are optional
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, _rootdn, _basedn, _passdn, _host='localhost',_port=389)
486
- _conn = LDAP::Conn.new(_host, _port)
487
- _conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
488
- _record.delete('dn')
489
- _conn.bind("#{_rootdn}", "#{_passdn}"){
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, _record, _rootdn, _basedn and _passdn are required, _host and _port are optional
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, _record, _rootdn, _basedn, _passdn, _host='localhost',_port=389)
509
- _conn = LDAP::Conn.new(_host, _port)
510
- _conn.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
511
- _record.delete('dn')
512
- _conn.bind("#{_rootdn}", "#{_passdn}"){
513
- begin
514
- _conn.delete("#{_dn}")
515
- _data = self.list_attributs
516
- _data.each{|_key,_value|
517
- _data[_key] = _value.to_a
518
- }
519
- _conn.add("#{_dn}", _data)
520
- return true
521
- rescue LDAP::ResultError
522
- return false
523
- end
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
- # run description of the library in interactive mode
528
- if $0 == __FILE__ then
529
- puts "#{File::basename(__FILE__)}:"
530
- puts 'this is a RUBY library file'
531
- puts "Copyright (c) Ultragreen"
532
- puts "Version : #{LIB_VERSION}"
533
- puts "Author : #{AUTHOR}"
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==#
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ldapmapper
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.3"
4
+ version: "1.4"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Romain GEORGES