ruby-activeldap 0.8.1 → 0.8.2
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/CHANGES +5 -0
- data/Manifest.txt +91 -25
- data/README +22 -0
- data/Rakefile +41 -8
- data/TODO +1 -6
- data/examples/config.yaml.example +5 -0
- data/examples/example.der +0 -0
- data/examples/example.jpg +0 -0
- data/examples/groupadd +41 -0
- data/examples/groupdel +35 -0
- data/examples/groupls +49 -0
- data/examples/groupmod +42 -0
- data/examples/lpasswd +55 -0
- data/examples/objects/group.rb +13 -0
- data/examples/objects/ou.rb +4 -0
- data/examples/objects/user.rb +20 -0
- data/examples/ouadd +38 -0
- data/examples/useradd +45 -0
- data/examples/useradd-binary +50 -0
- data/examples/userdel +34 -0
- data/examples/userls +50 -0
- data/examples/usermod +42 -0
- data/examples/usermod-binary-add +47 -0
- data/examples/usermod-binary-add-time +51 -0
- data/examples/usermod-binary-del +48 -0
- data/examples/usermod-lang-add +43 -0
- data/lib/active_ldap.rb +213 -214
- data/lib/active_ldap/adapter/base.rb +461 -0
- data/lib/active_ldap/adapter/ldap.rb +232 -0
- data/lib/active_ldap/adapter/ldap_ext.rb +69 -0
- data/lib/active_ldap/adapter/net_ldap.rb +288 -0
- data/lib/active_ldap/adapter/net_ldap_ext.rb +29 -0
- data/lib/active_ldap/association/belongs_to.rb +3 -1
- data/lib/active_ldap/association/belongs_to_many.rb +5 -6
- data/lib/active_ldap/association/has_many.rb +9 -17
- data/lib/active_ldap/association/has_many_wrap.rb +4 -5
- data/lib/active_ldap/attributes.rb +4 -0
- data/lib/active_ldap/base.rb +201 -56
- data/lib/active_ldap/configuration.rb +11 -1
- data/lib/active_ldap/connection.rb +15 -9
- data/lib/active_ldap/distinguished_name.rb +246 -0
- data/lib/active_ldap/ldap_error.rb +74 -0
- data/lib/active_ldap/object_class.rb +9 -5
- data/lib/active_ldap/schema.rb +50 -9
- data/lib/active_ldap/validations.rb +11 -13
- data/rails/plugin/active_ldap/generators/scaffold_al/scaffold_al_generator.rb +7 -0
- data/rails/plugin/active_ldap/generators/scaffold_al/templates/ldap.yml +21 -0
- data/rails/plugin/active_ldap/init.rb +10 -4
- data/test/al-test-utils.rb +46 -3
- data/test/run-test.rb +16 -4
- data/test/test-unit-ext/always-show-result.rb +28 -0
- data/test/test-unit-ext/priority.rb +163 -0
- data/test/test_adapter.rb +81 -0
- data/test/test_attributes.rb +8 -1
- data/test/test_base.rb +132 -3
- data/test/test_base_per_instance.rb +14 -3
- data/test/test_connection.rb +19 -0
- data/test/test_dn.rb +161 -0
- data/test/test_find.rb +24 -0
- data/test/test_object_class.rb +15 -2
- data/test/test_schema.rb +108 -1
- metadata +111 -41
- data/lib/active_ldap/adaptor/base.rb +0 -29
- data/lib/active_ldap/adaptor/ldap.rb +0 -466
- data/lib/active_ldap/ldap.rb +0 -113
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/ruby -W0
|
2
|
+
|
3
|
+
base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
4
|
+
$LOAD_PATH << File.join(base, "lib")
|
5
|
+
$LOAD_PATH << File.join(base, "examples")
|
6
|
+
|
7
|
+
require 'active_ldap'
|
8
|
+
require 'objects/user'
|
9
|
+
require 'objects/group'
|
10
|
+
|
11
|
+
argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
|
12
|
+
opts.banner += " USER_NAME CN UID"
|
13
|
+
end
|
14
|
+
|
15
|
+
if argv.size == 3
|
16
|
+
name, cn, uid = argv
|
17
|
+
else
|
18
|
+
$stderr.puts opts
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
pwb = Proc.new do |user|
|
23
|
+
ActiveLdap::Command.read_password("[#{user}] Password: ")
|
24
|
+
end
|
25
|
+
|
26
|
+
ActiveLdap::Base.establish_connection(:password_block => pwb,
|
27
|
+
:allow_anonymous => false)
|
28
|
+
|
29
|
+
unless User.exists?(name)
|
30
|
+
$stderr.puts("User #{name} doesn't exist.")
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
user = User.find(name)
|
35
|
+
user.cn = cn
|
36
|
+
user.uid_number = uid
|
37
|
+
user.gid_number = uid
|
38
|
+
|
39
|
+
if user.classes.include?('strongAuthenticationUser')
|
40
|
+
user.user_certificate = nil
|
41
|
+
user.remove_class('strongAuthenticationUser')
|
42
|
+
end
|
43
|
+
|
44
|
+
unless user.save
|
45
|
+
puts "failed"
|
46
|
+
puts user.errors.full_messages
|
47
|
+
exit 1
|
48
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/ruby -W0
|
2
|
+
|
3
|
+
base = File.expand_path(File.join(File.dirname(__FILE__), ".."))
|
4
|
+
$LOAD_PATH << File.join(base, "lib")
|
5
|
+
$LOAD_PATH << File.join(base, "examples")
|
6
|
+
|
7
|
+
require 'active_ldap'
|
8
|
+
require 'objects/user'
|
9
|
+
require 'objects/group'
|
10
|
+
|
11
|
+
argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
|
12
|
+
opts.banner += " USER_NAME CN UID"
|
13
|
+
end
|
14
|
+
|
15
|
+
if argv.size == 3
|
16
|
+
name, cn, uid = argv
|
17
|
+
else
|
18
|
+
$stderr.puts opts
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
pwb = Proc.new do |user|
|
23
|
+
ActiveLdap::Command.read_password("[#{user}] Password: ")
|
24
|
+
end
|
25
|
+
|
26
|
+
ActiveLdap::Base.establish_connection(:password_block => pwb,
|
27
|
+
:allow_anonymous => false)
|
28
|
+
|
29
|
+
unless User.exists?(name)
|
30
|
+
$stderr.puts("User #{name} doesn't exist.")
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
user = User.find(name)
|
35
|
+
user.cn = [cn, {'lang-en-us' => cn}]
|
36
|
+
user.uid_number = uid
|
37
|
+
user.gid_number = uid
|
38
|
+
|
39
|
+
unless user.save
|
40
|
+
puts "failed"
|
41
|
+
puts user.errors.full_messages
|
42
|
+
exit 1
|
43
|
+
end
|
data/lib/active_ldap.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
|
-
# = Ruby/ActiveLdap
|
2
|
+
# = Ruby/ActiveLdap
|
3
3
|
#
|
4
4
|
# "Ruby/ActiveLdap" Copyright (C) 2004,2005 Will Drewry mailto:will@alum.bu.edu
|
5
5
|
#
|
6
6
|
# == Introduction
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# Ruby/ActiveLdap is a novel way of interacting with LDAP. Most interaction with
|
9
9
|
# LDAP is done using clunky LDIFs, web interfaces, or with painful APIs that
|
10
10
|
# required a thick reference manual nearby. Ruby/ActiveLdap aims to fix that.
|
11
11
|
# Inspired by ActiveRecord[http://activerecord.rubyonrails.org], Ruby/ActiveLdap provides an
|
12
12
|
# object oriented interface to LDAP entries.
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# The target audience is system administrators and LDAP users everywhere that
|
15
15
|
# need quick, clean access to LDAP in Ruby.
|
16
|
-
#
|
16
|
+
#
|
17
17
|
# === What's LDAP?
|
18
|
-
#
|
18
|
+
#
|
19
19
|
# LDAP stands for "Lightweight Directory Access Protocol." Basically this means
|
20
20
|
# that it is the protocol used for accessing LDAP servers. LDAP servers
|
21
21
|
# lightweight directories. An LDAP server can contain anything from a simple
|
@@ -24,32 +24,32 @@
|
|
24
24
|
# assume some familiarity with using LDAP as a centralized authentication and
|
25
25
|
# authorization server for Unix systems. (Unfortunately, I've yet to try this
|
26
26
|
# against Microsoft's ActiveDirectory, despite what the name implies.)
|
27
|
-
#
|
28
|
-
# Further reading:
|
27
|
+
#
|
28
|
+
# Further reading:
|
29
29
|
# * RFC1777[http://www.faqs.org/rfcs/rfc1777.html] - Lightweight Directory Access Protocol
|
30
30
|
# * OpenLDAP[http://www.openldap.org]
|
31
|
-
#
|
31
|
+
#
|
32
32
|
# === So why use Ruby/ActiveLdap?
|
33
|
-
#
|
33
|
+
#
|
34
34
|
# Well if you like to fumble around in the dark, dank innards of LDAP, you can
|
35
35
|
# quit reading now. However, if you'd like a cleaner way to integrate LDAP in to
|
36
36
|
# your existing code, hopefully that's why you'll want to use Ruby/ActiveLdap.
|
37
|
-
#
|
37
|
+
#
|
38
38
|
# Using LDAP directly (even with the excellent Ruby/LDAP), leaves you bound to
|
39
39
|
# the world of the predefined LDAP API. While this API is important for many
|
40
40
|
# reasons, having to extract code out of LDAP search blocks and create huge
|
41
41
|
# arrays of LDAP.mod entries make code harder to read, less intuitive, and just
|
42
42
|
# less fun to write. Hopefully, Ruby/ActiveLdap will remedy all of these
|
43
43
|
# problems!
|
44
|
-
#
|
44
|
+
#
|
45
45
|
# == Getting Started
|
46
|
-
#
|
46
|
+
#
|
47
47
|
# Ruby/ActiveLdap does have some overhead when you get started. You must not
|
48
48
|
# only install the package and all of it's requirements, but you must also make
|
49
49
|
# customizations that will let it work in your environment.
|
50
|
-
#
|
50
|
+
#
|
51
51
|
# === Requirements
|
52
|
-
#
|
52
|
+
#
|
53
53
|
# * Ruby[http://www.ruby-lang.org] 1.8.x
|
54
54
|
# * Ruby/LDAP[http://ruby-ldap.sourceforge.net]
|
55
55
|
# * Log4r[http://log4r.sourceforge.net]
|
@@ -57,134 +57,134 @@
|
|
57
57
|
# * An LDAP server compatible with Ruby/LDAP: OpenLDAP[http://www.openldap.org], etc
|
58
58
|
# - Your LDAP server must allow root_dse queries to allow for schema queries
|
59
59
|
# * Examples also require: Ruby/Password[http://raa.ruby-lang.org/project/ruby-password/]
|
60
|
-
#
|
60
|
+
#
|
61
61
|
# === Installation
|
62
|
-
#
|
62
|
+
#
|
63
63
|
# Assuming all the requirements are installed, you can install by grabbing the latest tgz file from
|
64
64
|
# the download site[http://projects.dataspill.org/libraries/ruby/activeldap/download.html].
|
65
|
-
#
|
65
|
+
#
|
66
66
|
# The following steps will get the Ruby/ActiveLdap installed in no time!
|
67
|
-
#
|
67
|
+
#
|
68
68
|
# $ tar -xzvf ruby-activeldap-current.tgz
|
69
69
|
# $ cd ruby-activeldap-VERSION
|
70
|
-
#
|
70
|
+
#
|
71
71
|
# Edit lib/active_ldap/configuration.rb replacing values to match what will work
|
72
72
|
# with your LDAP servers. Please note that those variables are required, but can
|
73
73
|
# be overridden in any program as detailed later in this document. Also make
|
74
74
|
# sure that "ROOT" stays all upcase.
|
75
|
-
#
|
75
|
+
#
|
76
76
|
# Now run:
|
77
|
-
#
|
77
|
+
#
|
78
78
|
# $ ruby setup.rb config
|
79
79
|
# $ ruby setup.rb setup
|
80
80
|
# $ (as root) ruby setup.rb install
|
81
|
-
#
|
81
|
+
#
|
82
82
|
# Now as a quick test, you can run:
|
83
|
-
#
|
83
|
+
#
|
84
84
|
# $ irb
|
85
85
|
# irb> require 'active_ldap'
|
86
86
|
# => true
|
87
87
|
# irb> exit
|
88
|
-
#
|
88
|
+
#
|
89
89
|
# If the require returns false or an exception is raised, there has been a
|
90
90
|
# problem with the installation. You may need to customize what setup.rb does on
|
91
91
|
# install.
|
92
|
-
#
|
93
|
-
#
|
92
|
+
#
|
93
|
+
#
|
94
94
|
# === Customizations
|
95
|
-
#
|
95
|
+
#
|
96
96
|
# Now that Ruby/ActiveLdap is installed and working, we still have a few more
|
97
97
|
# steps to make it useful for programming.
|
98
|
-
#
|
98
|
+
#
|
99
99
|
# Let's say that you are writing a Ruby program for managing user and group
|
100
100
|
# accounts in LDAP. I will use this as the running example throughout the
|
101
101
|
# document.
|
102
|
-
#
|
102
|
+
#
|
103
103
|
# You will want to make a directory called 'ldapadmin' wherever is convenient. Under this directory,
|
104
104
|
# you'll want to make sure you have a 'lib' directory.
|
105
|
-
#
|
105
|
+
#
|
106
106
|
# $ cd ~
|
107
107
|
# $ mkdir ldapadmin
|
108
108
|
# $ cd ldapadmin
|
109
109
|
# $ mkdir lib
|
110
110
|
# $ cd lib
|
111
|
-
#
|
111
|
+
#
|
112
112
|
# The lib directory is where we'll be making customizations. You can, of course,
|
113
113
|
# make this changes somewhere in Ruby's default search path to make this
|
114
114
|
# accessible to every Ruby scripts. Enough of my babbling, I'm sure you'd like to
|
115
115
|
# know what we're going to put in lib/.
|
116
|
-
#
|
116
|
+
#
|
117
117
|
# We're going to put extension classes in there. What are extension classes you say . . .
|
118
|
-
#
|
119
|
-
#
|
118
|
+
#
|
119
|
+
#
|
120
120
|
# == Usage
|
121
|
-
#
|
121
|
+
#
|
122
122
|
# This section covers using Ruby/ActiveLdap from writing extension classes to
|
123
123
|
# writing applications that use them.
|
124
|
-
#
|
124
|
+
#
|
125
125
|
# Just to give a taste of what's to come, here is a quick example using irb:
|
126
|
-
#
|
126
|
+
#
|
127
127
|
# irb> require 'active_ldap'
|
128
|
-
#
|
128
|
+
#
|
129
129
|
# Here's an extension class that maps to the LDAP Group objects:
|
130
|
-
#
|
130
|
+
#
|
131
131
|
# irb> class Group < ActiveLdap::Base
|
132
132
|
# irb* ldap_mapping
|
133
133
|
# irb* end
|
134
|
-
#
|
134
|
+
#
|
135
135
|
# Here is the Group class in use:
|
136
|
-
#
|
136
|
+
#
|
137
137
|
# irb> all_groups = Group.find(:all, '*').collect {|group| group.cn}
|
138
138
|
# => ["root", "daemon", "bin", "sys", "adm", "tty", ..., "develop"]
|
139
|
-
#
|
139
|
+
#
|
140
140
|
# irb> group = Group.find("develop")
|
141
141
|
# => #<Group:0x..........>
|
142
|
-
#
|
142
|
+
#
|
143
143
|
# irb> group.members.collect {|member| member.uid}
|
144
144
|
# => ["drewry"]
|
145
|
-
#
|
145
|
+
#
|
146
146
|
# irb> group.cn
|
147
147
|
# => "develop"
|
148
|
-
#
|
148
|
+
#
|
149
149
|
# irb> group.gid_number
|
150
150
|
# => "1003"
|
151
|
-
#
|
151
|
+
#
|
152
152
|
# That's it! No let's get back in to it.
|
153
153
|
#
|
154
154
|
# === Extension Classes
|
155
|
-
#
|
155
|
+
#
|
156
156
|
# Extension classes are classes that are subclassed from ActiveLdap::Base. They
|
157
157
|
# are used to represent objects in your LDAP server abstractly.
|
158
|
-
#
|
158
|
+
#
|
159
159
|
# ==== Why do I need them?
|
160
|
-
#
|
160
|
+
#
|
161
161
|
# Extension classes are what make Ruby/ActiveLdap "active"! They do all the
|
162
162
|
# background work to make easy-to-use objects by mapping the LDAP object's
|
163
163
|
# attributes on to a Ruby class.
|
164
|
-
#
|
165
|
-
#
|
164
|
+
#
|
165
|
+
#
|
166
166
|
# ==== Special Methods
|
167
|
-
#
|
167
|
+
#
|
168
168
|
# I will briefly talk about each of the methods you can use when defining an
|
169
169
|
# extension class. In the above example, I only made one special method call
|
170
170
|
# inside the Group class. More than likely, you will want to more than that.
|
171
|
-
#
|
171
|
+
#
|
172
172
|
# ===== ldap_mapping
|
173
|
-
#
|
173
|
+
#
|
174
174
|
# ldap_mapping is the only required method to setup an extension class for use
|
175
175
|
# with Ruby/ActiveLdap. It must be called inside of a subclass as shown above.
|
176
|
-
#
|
176
|
+
#
|
177
177
|
# Below is a much more realistic Group class:
|
178
|
-
#
|
178
|
+
#
|
179
179
|
# class Group < ActiveLdap::Base
|
180
180
|
# ldap_mapping :dn_attribute => 'cn',
|
181
181
|
# :prefix => 'ou=Groups', :classes => ['top', 'posixGroup']
|
182
182
|
# :scope => LDAP::LDAP_SCOPE_ONELEVEL
|
183
183
|
# end
|
184
|
-
#
|
185
|
-
# As you can see, this method is used for defining how this class maps in to LDAP. Let's say that
|
184
|
+
#
|
185
|
+
# As you can see, this method is used for defining how this class maps in to LDAP. Let's say that
|
186
186
|
# my LDAP tree looks something like this:
|
187
|
-
#
|
187
|
+
#
|
188
188
|
# * dc=dataspill,dc=org
|
189
189
|
# |- ou=People,dc=dataspill,dc=org
|
190
190
|
# |+ ou=Groups,dc=dataspill,dc=org
|
@@ -192,24 +192,24 @@
|
|
192
192
|
# |- cn=develop,ou=Groups,dc=dataspill,dc=org
|
193
193
|
# |- cn=root,ou=Groups,dc=dataspill,dc=org
|
194
194
|
# |- ...
|
195
|
-
#
|
195
|
+
#
|
196
196
|
# Under ou=People I store user objects, and under ou=Groups, I store group
|
197
197
|
# objects. What |ldap_mapping| has done is mapped the class in to the LDAP tree
|
198
198
|
# abstractly. With the given :dnattr and :prefix, it will only work for entries
|
199
199
|
# under ou=Groups,dc=dataspill,dc=org using the primary attribute 'cn' as the
|
200
200
|
# beginning of the distinguished name.
|
201
|
-
#
|
201
|
+
#
|
202
202
|
# Just for clarity, here's how the arguments map out:
|
203
|
-
#
|
203
|
+
#
|
204
204
|
# cn=develop,ou=Groups,dc=dataspill,dc=org
|
205
205
|
# ^^ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
|
206
206
|
# :dn_attribute | |
|
207
207
|
# :prefix |
|
208
208
|
# :base from configuration.rb
|
209
|
-
#
|
209
|
+
#
|
210
210
|
# :scope tells ActiveLdap to only search under ou=Groups, and not to look deeper
|
211
211
|
# for dnattr matches. (e.g. cn=develop,ou=DevGroups,ou=Groups,dc=dataspill,dc=org)
|
212
|
-
#
|
212
|
+
#
|
213
213
|
# Something's missing: :classes. :classes is used to tell Ruby/ActiveLdap what
|
214
214
|
# the minimum requirement is when creating a new object. LDAP uses objectClasses
|
215
215
|
# to define what attributes a LDAP object may have. Ruby/ActiveLdap needs to know
|
@@ -222,48 +222,48 @@
|
|
222
222
|
# implementation choices with most LDAP servers, once an object is created, its
|
223
223
|
# structural objectclasses may not be removed (or replaced). Setting a sane default
|
224
224
|
# may help avoid programmer error later.
|
225
|
-
#
|
225
|
+
#
|
226
226
|
# :classes isn't the only optional argument. If :dn_attribute is left off,
|
227
227
|
# it defaults to underscored class name or 'cn'. If :prefix is left off,
|
228
228
|
# it will default to 'ou=PLURALIZED_CLASSNAME'. In this
|
229
229
|
# case, it would be 'ou=Groups'.
|
230
|
-
#
|
230
|
+
#
|
231
231
|
# :classes should be an Array. :dn_attribute should be a String and so should
|
232
232
|
# :prefix.
|
233
|
-
#
|
234
|
-
#
|
233
|
+
#
|
234
|
+
#
|
235
235
|
# ===== belongs_to
|
236
|
-
#
|
236
|
+
#
|
237
237
|
# This method allows an extension class to make use of other extension classes
|
238
238
|
# tying objects together across the LDAP tree. Often, user objects will be
|
239
239
|
# members of, or belong_to, Group objects.
|
240
|
-
#
|
240
|
+
#
|
241
241
|
# * dc=dataspill,dc=org
|
242
242
|
# |+ ou=People,dc=dataspill,dc=org
|
243
243
|
# \
|
244
244
|
# |- uid=drewry,ou=People,dc=dataspill,dc=org
|
245
245
|
# |- ou=Groups,dc=dataspill,dc=org
|
246
|
-
#
|
247
|
-
#
|
246
|
+
#
|
247
|
+
#
|
248
248
|
# In the above tree, one such example would be user 'drewry' who is a part of the
|
249
249
|
# group 'develop'. You can see this by looking at the 'memberUid' field of 'develop'.
|
250
|
-
#
|
250
|
+
#
|
251
251
|
# irb> develop = Group.find('develop')
|
252
252
|
# => ...
|
253
253
|
# irb> develop.memberUid
|
254
254
|
# => ['drewry', 'builder']
|
255
|
-
#
|
255
|
+
#
|
256
256
|
# If we look at the LDAP entry for 'drewry', we do not see any references to
|
257
257
|
# group 'develop'. In order to remedy that, we can use belongs_to
|
258
|
-
#
|
258
|
+
#
|
259
259
|
# irb> class User < ActiveLdap::Base
|
260
260
|
# irb* ldap_mapping :dn_attribute => 'uid', :prefix => 'People', :classes => ['top','account']
|
261
261
|
# irb* belongs_to :groups, :class => 'Group', :many => 'memberUid', :foreign_key => 'uid'
|
262
262
|
# irb* end
|
263
|
-
#
|
263
|
+
#
|
264
264
|
# Now, class User will have a method called 'groups' which will retrieve all
|
265
265
|
# Group objects that a user is in.
|
266
|
-
#
|
266
|
+
#
|
267
267
|
# irb> me = User.find('drewry')
|
268
268
|
# irb> me.groups
|
269
269
|
# => [#<Group:0x000001 ...>, #<Group:0x000002 ...>, ...]
|
@@ -273,16 +273,16 @@
|
|
273
273
|
# "develop"
|
274
274
|
# => nil
|
275
275
|
# (Note: nil is just there to make the output cleaner...)
|
276
|
-
#
|
276
|
+
#
|
277
277
|
# TIP: If you weren't sure what the distinguished name attribute was for Group,
|
278
278
|
# you could also do the following:
|
279
|
-
#
|
279
|
+
#
|
280
280
|
# irb> me.groups.each { |group| p group.id };nil
|
281
281
|
# "cdrom"
|
282
282
|
# "audio"
|
283
283
|
# "develop"
|
284
284
|
# => nil
|
285
|
-
#
|
285
|
+
#
|
286
286
|
# Now let's talk about the arguments. The first argument is the name of the
|
287
287
|
# method you wish to create. In this case, we created a method called groups
|
288
288
|
# using the symbol :groups. The next collection of arguments are actually a Hash
|
@@ -294,78 +294,78 @@
|
|
294
294
|
# should be looked up in Group under the primary key. If :foreign_key is left
|
295
295
|
# off of the argument list, it is assumed to be the dn_attribute. With this in
|
296
296
|
# mind, the above definition could become:
|
297
|
-
#
|
297
|
+
#
|
298
298
|
# irb> class User < ActiveLdap::Base
|
299
299
|
# irb* ldap_mapping :dnattr => 'uid', :prefix => 'People', :classes => ['top','account']
|
300
300
|
# irb* belongs_to :groups, :class => 'Group', :many => 'memberUid'
|
301
301
|
# irb* end
|
302
|
-
#
|
302
|
+
#
|
303
303
|
# In addition, you can do simple membership tests by doing the following:
|
304
|
-
#
|
304
|
+
#
|
305
305
|
# irb> me.groups.member? 'root'
|
306
306
|
# => false
|
307
307
|
# irb> me.groups.member? 'develop'
|
308
308
|
# => true
|
309
|
-
#
|
309
|
+
#
|
310
310
|
# ===== has_many
|
311
|
-
#
|
311
|
+
#
|
312
312
|
# This method is the opposite of belongs_to. Instead of checking other objects in
|
313
313
|
# other parts of the LDAP tree to see if you belong to them, you have multiple
|
314
314
|
# objects from other trees listed in your object. To show this, we can just
|
315
315
|
# invert the example from above:
|
316
|
-
#
|
316
|
+
#
|
317
317
|
# class Group < ActiveLdap::Base
|
318
318
|
# ldap_mapping :dn_attribute => 'cn', :prefix => 'ou=Groups', :classes => ['top', 'posixGroup']
|
319
319
|
# has_many :members, :class => "User", :wrap => "memberUid", :primary_key => 'uid'
|
320
320
|
# end
|
321
|
-
#
|
321
|
+
#
|
322
322
|
# Now we can see that group develop has user 'drewry' as a member, and it can
|
323
323
|
# even return all responses in object form just like belongs_to methods.
|
324
|
-
#
|
324
|
+
#
|
325
325
|
# irb> develop = Group.find('develop')
|
326
326
|
# => ...
|
327
327
|
# irb> develop.members
|
328
328
|
# => [#<User:0x000001 ...>, #<User:...>]
|
329
|
-
#
|
330
|
-
#
|
329
|
+
#
|
330
|
+
#
|
331
331
|
# The arguments for has_many follow the exact same idea that belongs_to's
|
332
332
|
# arguments followed. :wrap's contents are used to search for matching
|
333
333
|
# :primary_key content. If :primary_key is not specified, it defaults to the
|
334
334
|
# dn_attribute of the specified :class.
|
335
|
-
#
|
335
|
+
#
|
336
336
|
# === Using these new classes
|
337
|
-
#
|
337
|
+
#
|
338
338
|
# These new classes have many method calls. Many of them are automatically
|
339
339
|
# generated to provide access to the LDAP object's attributes. Other were defined
|
340
340
|
# during class creation by special methods like belongs_to. There are a few other
|
341
341
|
# methods that do not fall in to these categories.
|
342
|
-
#
|
343
|
-
#
|
342
|
+
#
|
343
|
+
#
|
344
344
|
# ==== .find
|
345
|
-
#
|
345
|
+
#
|
346
346
|
# .find is a class method that is accessible from any subclass of Base that has
|
347
347
|
# 'ldap_mapping' called. When called it returns the first match of the given
|
348
348
|
# class.
|
349
|
-
#
|
349
|
+
#
|
350
350
|
# irb> Group.find('*').cn
|
351
351
|
# => "root"
|
352
|
-
#
|
352
|
+
#
|
353
353
|
# In this simple example, Group.find took the search string of 'deve*' and
|
354
354
|
# searched for the first match in Group where the dnattr matched the query. This
|
355
355
|
# is the simplest example of .find.
|
356
|
-
#
|
356
|
+
#
|
357
357
|
# irb> Group.find(:all, '*').collect {|group| group.cn}
|
358
358
|
# => ["root", "daemon", "bin", "sys", "adm", "tty", ..., "develop"]
|
359
|
-
#
|
359
|
+
#
|
360
360
|
# Here .find(:all) returns all matches to the same query. Both .find and
|
361
361
|
# .find(:all) also can take more expressive arguments:
|
362
|
-
#
|
362
|
+
#
|
363
363
|
# irb> Group.find(:all, :attribute => 'gidNumber', :value => '1003').collect {|group| group.cn}
|
364
364
|
# => ["develop"]
|
365
|
-
#
|
365
|
+
#
|
366
366
|
# So it is pretty clear what :attribute and :value do - they are used to query as
|
367
367
|
# :attribute=:value.
|
368
|
-
#
|
368
|
+
#
|
369
369
|
# If :attribute is unspecified, it defaults to the dn_attribute.
|
370
370
|
#
|
371
371
|
# It is also possible to override :attribute and :value by specifying :filter. This
|
@@ -387,87 +387,83 @@
|
|
387
387
|
# * :attributes defaults to [] and is the list of attributes you want back. Empty means all of them.
|
388
388
|
#
|
389
389
|
# ==== #valid?
|
390
|
-
#
|
390
|
+
#
|
391
391
|
# valid? is a method that verifies that all attributes that are required by the
|
392
392
|
# objects current objectClasses are populated.
|
393
|
-
#
|
393
|
+
#
|
394
394
|
# ==== #save
|
395
|
-
#
|
395
|
+
#
|
396
396
|
# save is a method that writes any changes to an object back to the LDAP server.
|
397
397
|
# It automatically handles the addition of new objects, and the modification of
|
398
398
|
# existing ones.
|
399
|
-
#
|
399
|
+
#
|
400
400
|
# ==== .exists?
|
401
|
-
#
|
401
|
+
#
|
402
402
|
# exists? is a simple method which returns true is the current object exists in
|
403
403
|
# LDAP, or false if it does not.
|
404
|
-
#
|
404
|
+
#
|
405
405
|
# irb> User.exists?("dshadsadsa")
|
406
406
|
# => false
|
407
|
-
#
|
408
|
-
#
|
407
|
+
#
|
408
|
+
#
|
409
409
|
# === ActiveLdap::Base
|
410
|
-
#
|
410
|
+
#
|
411
411
|
# ActiveLdap::Base has come up a number of times in the examples above. Every
|
412
412
|
# time, it was being used as the super class for the wrapper objects. While this
|
413
413
|
# is it's main purpose, it also handles quite a bit more in the background.
|
414
|
-
#
|
414
|
+
#
|
415
415
|
# ==== What is it?
|
416
|
-
#
|
416
|
+
#
|
417
417
|
# ActiveLdap::Base is the heart of Ruby/ActiveLdap. It does all the schema
|
418
418
|
# parsing for validation and attribute-to-method mangling as well as manage the
|
419
419
|
# connection to LDAP.
|
420
|
-
#
|
420
|
+
#
|
421
421
|
# ===== establish_connection
|
422
|
-
#
|
422
|
+
#
|
423
423
|
# Base.establish_connection takes many (optional) arguments and is used to
|
424
424
|
# connect to the LDAP server. Sometimes you will want to connect anonymously
|
425
|
-
# and other times over TLS with user credentials. Base.
|
426
|
-
# all of that for you.
|
427
|
-
#
|
428
|
-
#
|
425
|
+
# and other times over TLS with user credentials. Base.establish_connection is
|
426
|
+
# here to do all of that for you.
|
427
|
+
#
|
428
|
+
#
|
429
429
|
# By default, if you call any subclass of Base, such as Group, it will call
|
430
430
|
# Base.establish_connection() if these is no active LDAP connection. If your
|
431
431
|
# server allows anonymous binding, and you only want to access data in a
|
432
432
|
# read-only fashion, you won't need to call Base.establish_connection. Here
|
433
433
|
# is a fully parameterized call:
|
434
|
-
#
|
435
|
-
# Base.
|
434
|
+
#
|
435
|
+
# Base.establish_connection(
|
436
436
|
# :host => 'ldap.dataspill.org',
|
437
437
|
# :port => 389,
|
438
438
|
# :base => 'dc=dataspill,dc=org',
|
439
|
-
# :bind_format => "uid=%s,ou=People,dc=dataspill,dc=org",
|
440
439
|
# :logger => log4r_obj,
|
441
|
-
# :
|
440
|
+
# :bind_dn => "uid=drewry,ou=People,dc=dataspill,dc=org",
|
442
441
|
# :password_block => Proc.new { 'password12345' },
|
443
442
|
# :allow_anonymous => false,
|
444
443
|
# :try_sasl => false
|
445
444
|
# )
|
446
|
-
#
|
445
|
+
#
|
447
446
|
# There are quite a few arguments, but luckily many of them have safe defaults:
|
448
447
|
# * :host defaults to @@host from configuration.rb waaay back at the setup.rb stage.@
|
449
448
|
# * :port defaults to @@port from configuration.rb as well
|
450
449
|
# * :base defaults to Base.base() from configuration.rb
|
451
|
-
# * :
|
450
|
+
# * :bind_dn defaults @@bind_format from configuration.rb
|
452
451
|
# * :logger defaults to a Log4r object that prints fatal messages to stderr
|
453
|
-
# * :user defaults to ENV['user']
|
454
452
|
# * :password_block defaults to nil
|
455
453
|
# * :allow_anonymous defaults to true
|
456
454
|
# * :try_sasl defaults to false - see Advanced Topics for more on this one.
|
457
|
-
#
|
458
|
-
#
|
455
|
+
#
|
456
|
+
#
|
459
457
|
# Most of these are obvious, but I'll step through them for completeness:
|
460
458
|
# * :host defines the LDAP server hostname to connect to.
|
461
459
|
# * :port defines the LDAP server port to connect to.
|
462
460
|
# * :method defines the type of connection - :tls, :ssl, :plain
|
463
461
|
# * :base specifies the LDAP search base to use with the prefixes defined in all
|
464
462
|
# subclasses.
|
465
|
-
# * :
|
463
|
+
# * :bind_dn specifies what your server expects when attempting to bind with
|
466
464
|
# credentials.
|
467
465
|
# * :logger accepts a custom log4r object to integrate with any other logging
|
468
466
|
# your application uses.
|
469
|
-
# * :user gives the username to substitute into bind_format for binding with
|
470
|
-
# credentials
|
471
467
|
# * :password_block, if defined, give the Proc block for acquiring the password
|
472
468
|
# * :password, if defined, give the user's password as a String
|
473
469
|
# * :store_password indicates whether the password should be stored, or if used
|
@@ -483,13 +479,13 @@
|
|
483
479
|
# * :timeout - time in seconds - defaults to disabled. This CAN interrupt search() requests. Be warned.
|
484
480
|
# * :retry_on_timeout - whether to reconnect when timeouts occur. Defaults to true
|
485
481
|
# See lib/configuration.rb for defaults for each option
|
486
|
-
#
|
482
|
+
#
|
487
483
|
# Base.establish_connection both connects and binds in one step. It follows
|
488
484
|
# roughly the following approach:
|
489
|
-
#
|
485
|
+
#
|
490
486
|
# * Connect to host:port using :method
|
491
|
-
#
|
492
|
-
# * If
|
487
|
+
#
|
488
|
+
# * If bind_dn and password_block/password, attempt to bind with credentials.
|
493
489
|
# * If that fails or no password_block and anonymous allowed, attempt to bind
|
494
490
|
# anonymously.
|
495
491
|
# * If that fails, error out.
|
@@ -497,62 +493,62 @@
|
|
497
493
|
# On connect, the configuration options passed in are stored in an internal class variable
|
498
494
|
# @configuration which is used to cache the information without ditching the defaults passed in
|
499
495
|
# from configuration.rb
|
500
|
-
#
|
496
|
+
#
|
501
497
|
# ===== connection
|
502
|
-
#
|
498
|
+
#
|
503
499
|
# Base.connection returns the ActiveLdap::Connection object.
|
504
|
-
#
|
500
|
+
#
|
505
501
|
# === Exceptions
|
506
|
-
#
|
502
|
+
#
|
507
503
|
# There are a few custom exceptions used in Ruby/ActiveLdap. They are detailed below.
|
508
|
-
#
|
504
|
+
#
|
509
505
|
# ==== DeleteError
|
510
|
-
#
|
506
|
+
#
|
511
507
|
# This exception is raised when #delete fails. It will include LDAP error
|
512
508
|
# information that was passed up during the error.
|
513
|
-
#
|
509
|
+
#
|
514
510
|
# ==== SaveError
|
515
|
-
#
|
511
|
+
#
|
516
512
|
# This exception is raised when there is a problem in #save updating or creating
|
517
513
|
# an LDAP entry. Often the error messages are cryptic. Looking at the server
|
518
514
|
# logs or doing an Ethereal[http://www.ethereal.com] dump of the connection will
|
519
515
|
# often provide better insight.
|
520
|
-
#
|
516
|
+
#
|
521
517
|
# ==== AuthenticationError
|
522
|
-
#
|
518
|
+
#
|
523
519
|
# This exception is raised during Base.establish_connection if no valid authentication methods
|
524
520
|
# succeeded.
|
525
|
-
#
|
521
|
+
#
|
526
522
|
# ==== ConnectionError
|
527
|
-
#
|
528
|
-
# This exception is raised during Base.
|
529
|
-
# LDAP server could be created. Check you configuration.rb,
|
530
|
-
# arguments, and network connectivity! Also check
|
531
|
-
# if it ever saw the request.
|
523
|
+
#
|
524
|
+
# This exception is raised during Base.establish_connection if no valid
|
525
|
+
# connection to the LDAP server could be created. Check you configuration.rb,
|
526
|
+
# Base.establish_connection arguments, and network connectivity! Also check
|
527
|
+
# your LDAP server logs to see if it ever saw the request.
|
532
528
|
#
|
533
529
|
# ==== ObjectClassError
|
534
530
|
#
|
535
531
|
# This exception is raised when an object class is used that is not defined
|
536
532
|
# in the schema.
|
537
|
-
#
|
533
|
+
#
|
538
534
|
# === Others
|
539
|
-
#
|
535
|
+
#
|
540
536
|
# Other exceptions may be raised by the Ruby/LDAP module, or by other subsystems.
|
541
537
|
# If you get one of these exceptions and think it should be wrapped, write me an
|
542
538
|
# email and let me know where it is and what you expected. For faster results,
|
543
539
|
# email a patch!
|
544
|
-
#
|
540
|
+
#
|
545
541
|
# === Putting it all together
|
546
|
-
#
|
542
|
+
#
|
547
543
|
# Now that all of the components of Ruby/ActiveLdap have been covered, it's time
|
548
544
|
# to put it all together! The rest of this section will show the steps to setup
|
549
545
|
# example user and group management scripts for use with the LDAP tree described
|
550
546
|
# above.
|
551
|
-
#
|
547
|
+
#
|
552
548
|
# All of the scripts here are in the package's examples/ directory.
|
553
|
-
#
|
549
|
+
#
|
554
550
|
# ==== Setting up lib/
|
555
|
-
#
|
551
|
+
#
|
556
552
|
# In ldapadmin/lib/ create the file user.rb:
|
557
553
|
# cat <<EOF
|
558
554
|
# class User < ActiveLdap::Base
|
@@ -560,7 +556,7 @@
|
|
560
556
|
# belongs_to :groups, :class => 'Group', :wrap => 'memberUid'
|
561
557
|
# end
|
562
558
|
# EOF
|
563
|
-
#
|
559
|
+
#
|
564
560
|
# In ldapadmin/lib/ create the file group.rb:
|
565
561
|
# cat <<EOF
|
566
562
|
# class Group < ActiveLdap::Base
|
@@ -569,20 +565,20 @@
|
|
569
565
|
# has_many :primary_members, :class => 'User', :foreign_key => 'gidNumber', :primary_key => 'gidNumber'
|
570
566
|
# end # Group
|
571
567
|
# EOF
|
572
|
-
#
|
568
|
+
#
|
573
569
|
# Now, we can write some small scripts to do simple management tasks.
|
574
|
-
#
|
570
|
+
#
|
575
571
|
# ==== Creating LDAP entries
|
576
|
-
#
|
572
|
+
#
|
577
573
|
# Now let's create a really dumb script for adding users - ldapadmin/useradd:
|
578
|
-
#
|
574
|
+
#
|
579
575
|
# #!/usr/bin/ruby -W0
|
580
|
-
#
|
576
|
+
#
|
581
577
|
# require 'active_ldap'
|
582
578
|
# require 'lib/user'
|
583
579
|
# require 'lib/group'
|
584
580
|
# require 'password'
|
585
|
-
#
|
581
|
+
#
|
586
582
|
# argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
|
587
583
|
# opts.banner += " USER_NAME CN UID"
|
588
584
|
# end
|
@@ -620,15 +616,15 @@
|
|
620
616
|
# end
|
621
617
|
#
|
622
618
|
# ==== Managing LDAP entries
|
623
|
-
#
|
619
|
+
#
|
624
620
|
# Now let's create another dumb script for modifying users - ldapadmin/usermod:
|
625
|
-
#
|
621
|
+
#
|
626
622
|
# #!/usr/bin/ruby -W0
|
627
|
-
#
|
623
|
+
#
|
628
624
|
# require 'active_ldap'
|
629
625
|
# require 'lib/user'
|
630
626
|
# require 'lib/group'
|
631
|
-
#
|
627
|
+
#
|
632
628
|
# argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
|
633
629
|
# opts.banner += " USER_NAME CN UID"
|
634
630
|
# end
|
@@ -663,16 +659,16 @@
|
|
663
659
|
# end
|
664
660
|
#
|
665
661
|
# ==== Removing LDAP entries
|
666
|
-
#
|
662
|
+
#
|
667
663
|
# And finally, a dumb script for removing user - ldapadmin/userdel:
|
668
|
-
#
|
669
|
-
#
|
664
|
+
#
|
665
|
+
#
|
670
666
|
# #!/usr/bin/ruby -W0
|
671
|
-
#
|
667
|
+
#
|
672
668
|
# require 'active_ldap'
|
673
669
|
# require 'lib/user'
|
674
670
|
# require 'lib/group'
|
675
|
-
#
|
671
|
+
#
|
676
672
|
# argv, opts, options = ActiveLdap::Command.parse_options do |opts, options|
|
677
673
|
# opts.banner += " USER_NAME"
|
678
674
|
# end
|
@@ -699,9 +695,9 @@
|
|
699
695
|
# User.destroy(name)
|
700
696
|
#
|
701
697
|
# === Advanced Topics
|
702
|
-
#
|
698
|
+
#
|
703
699
|
# Below are some situation tips and tricks to get the most out of Ruby/ActiveLdap.
|
704
|
-
#
|
700
|
+
#
|
705
701
|
#
|
706
702
|
# ==== Binary data and other subtypes
|
707
703
|
#
|
@@ -721,14 +717,14 @@
|
|
721
717
|
# => ...
|
722
718
|
# irb> user.save
|
723
719
|
#
|
724
|
-
# So that's a lot to take in. Here's what is going on. I just set the LDAP
|
720
|
+
# So that's a lot to take in. Here's what is going on. I just set the LDAP
|
725
721
|
# object's cn to "wad" and cn:lang-en-us to ["wad", "Will Drewry"].
|
726
722
|
# Anytime a LDAP subtype is required, you must encapsulate the data in a Hash.
|
727
723
|
#
|
728
724
|
# But wait a minute, I just read in a binary certificate without wrapping it up.
|
729
|
-
# So any binary attribute _that requires ;binary subtyping_ will automagically
|
730
|
-
# get wrapped in {'binary' => value} if you don't do it. This keeps your #writes
|
731
|
-
# from breaking, and my code from crying. For correctness, I could have easily
|
725
|
+
# So any binary attribute _that requires ;binary subtyping_ will automagically
|
726
|
+
# get wrapped in {'binary' => value} if you don't do it. This keeps your #writes
|
727
|
+
# from breaking, and my code from crying. For correctness, I could have easily
|
732
728
|
# done the following:
|
733
729
|
#
|
734
730
|
# irb> user.user_certificate = {'binary' => File.read('example.der')}
|
@@ -737,37 +733,37 @@
|
|
737
733
|
# One example is jpegPhoto. You can use it as jpegPhoto;binary or just as jpegPhoto.
|
738
734
|
# Since the schema dictates that it is a binary value, Ruby/ActiveLdap will write
|
739
735
|
# it as binary, but the subtype will not be automatically appended as above. The
|
740
|
-
# use of the subtype on attributes like jpegPhoto is ultimately decided by the
|
736
|
+
# use of the subtype on attributes like jpegPhoto is ultimately decided by the
|
741
737
|
# LDAP site policy and not by any programmatic means.
|
742
738
|
#
|
743
739
|
# The only subtypes defined in LDAPv3 are lang-* and binary. These can be nested
|
744
740
|
# though:
|
745
741
|
#
|
746
742
|
# irb> user.cn = [{'lang-JP-jp' => {'binary' => 'somejp'}}]
|
747
|
-
#
|
743
|
+
#
|
748
744
|
# As I understand it, OpenLDAP does not support nested subtypes, but some
|
749
745
|
# documentation I've read suggests that Netscape's LDAP server does. I only
|
750
|
-
# have access to OpenLDAP. If anyone tests this out, please let me know how it
|
746
|
+
# have access to OpenLDAP. If anyone tests this out, please let me know how it
|
751
747
|
# goes!
|
752
748
|
#
|
753
749
|
#
|
754
750
|
# And that pretty much wraps up this section.
|
755
751
|
#
|
756
752
|
# ==== Further integration with your environment aka namespacing
|
757
|
-
#
|
753
|
+
#
|
758
754
|
# If you want this to cleanly integrate into your system-wide Ruby include path,
|
759
755
|
# you should put your extension classes inside a custom module.
|
760
|
-
#
|
761
|
-
#
|
756
|
+
#
|
757
|
+
#
|
762
758
|
# Example:
|
763
|
-
#
|
759
|
+
#
|
764
760
|
# ./myldap.rb:
|
765
761
|
# require 'active_ldap'
|
766
762
|
# require 'myldap/user'
|
767
763
|
# require 'myldap/group'
|
768
764
|
# module MyLDAP
|
769
765
|
# end
|
770
|
-
#
|
766
|
+
#
|
771
767
|
# ./myldap/user.rb:
|
772
768
|
# module MyLDAP
|
773
769
|
# class User < ActiveLdap::Base
|
@@ -775,7 +771,7 @@
|
|
775
771
|
# belongs_to :groups, :class => 'MyLDAP::Group', :many => 'memberUid'
|
776
772
|
# end
|
777
773
|
# end
|
778
|
-
#
|
774
|
+
#
|
779
775
|
# ./myldap/group.rb:
|
780
776
|
# module MyLDAP
|
781
777
|
# class Group < ActiveLdap::Base
|
@@ -784,21 +780,21 @@
|
|
784
780
|
# has_many :primary_members, :class => 'MyLDAP::User', :foreign_key => 'gidNumber', :primary_key => 'gidNumber'
|
785
781
|
# end
|
786
782
|
# end
|
787
|
-
#
|
783
|
+
#
|
788
784
|
# Now in your local applications, you can call
|
789
|
-
#
|
785
|
+
#
|
790
786
|
# require 'myldap'
|
791
|
-
#
|
787
|
+
#
|
792
788
|
# MyLDAP::Group.new('foo')
|
793
789
|
# ...
|
794
|
-
#
|
790
|
+
#
|
795
791
|
# and everything should work well.
|
796
|
-
#
|
792
|
+
#
|
797
793
|
#
|
798
794
|
# ==== force array results for single values
|
799
795
|
#
|
800
|
-
# Even though Ruby/ActiveLdap attempts to maintain programmatic ease by
|
801
|
-
# returning Array values only. By specifying 'true' as an argument to
|
796
|
+
# Even though Ruby/ActiveLdap attempts to maintain programmatic ease by
|
797
|
+
# returning Array values only. By specifying 'true' as an argument to
|
802
798
|
# any attribute method you will get back a Array if it is single value.
|
803
799
|
# Here's an example:
|
804
800
|
#
|
@@ -808,33 +804,33 @@
|
|
808
804
|
# => ["Will Drewry"]
|
809
805
|
#
|
810
806
|
# ==== Dynamic attribute crawling
|
811
|
-
#
|
812
|
-
# If you use tab completion in irb, you'll notice that you /can/ tab complete the dynamic
|
813
|
-
# attribute methods. You can still see which methods are for attributes using
|
807
|
+
#
|
808
|
+
# If you use tab completion in irb, you'll notice that you /can/ tab complete the dynamic
|
809
|
+
# attribute methods. You can still see which methods are for attributes using
|
814
810
|
# Base#attribute_names:
|
815
|
-
#
|
811
|
+
#
|
816
812
|
# irb> d = Group.new('develop')
|
817
813
|
# => ...
|
818
814
|
# irb> d.attribute_names
|
819
815
|
# => ["gidNumber", "cn", "memberUid", "commonName", "description", "userPassword", "objectClass"]
|
820
|
-
#
|
821
|
-
#
|
816
|
+
#
|
817
|
+
#
|
822
818
|
# ==== Juggling multiple LDAP connections
|
823
|
-
#
|
819
|
+
#
|
824
820
|
# In the same vein as the last tip, you can use multiple LDAP connections by
|
825
821
|
# per class as follows:
|
826
|
-
#
|
822
|
+
#
|
827
823
|
# irb> anon_class = Class.new(Base)
|
828
824
|
# => ...
|
829
825
|
# irb> anon_class.establish_connection
|
830
826
|
# => ...
|
831
827
|
# irb> auth_class = Class.new(Base)
|
832
828
|
# => ...
|
833
|
-
# irb> auth_class.establish_connection(password_block => {'mypass'})
|
829
|
+
# irb> auth_class.establish_connection(:password_block => {'mypass'})
|
834
830
|
# => ...
|
835
|
-
#
|
831
|
+
#
|
836
832
|
# This can be useful for doing authentication tests and other such tricks.
|
837
|
-
#
|
833
|
+
#
|
838
834
|
# ==== :try_sasl
|
839
835
|
#
|
840
836
|
# If you have the Ruby/LDAP package with the SASL/GSSAPI patch from Ian
|
@@ -898,7 +894,7 @@
|
|
898
894
|
# == Limitations
|
899
895
|
#
|
900
896
|
# === Speed
|
901
|
-
#
|
897
|
+
#
|
902
898
|
# Currently, Ruby/ActiveLdap could be faster. I have some recursive type
|
903
899
|
# checking going on which slows object creation down, and I'm sure there
|
904
900
|
# are many, many other places optimizations can be done. Feel free
|
@@ -911,9 +907,6 @@
|
|
911
907
|
# package, and I'd like to see it prove helpful to more people than just myself.
|
912
908
|
#
|
913
909
|
|
914
|
-
# Blanket warning hiding. Remove for debugging
|
915
|
-
$VERBOSE, verbose = false, $VERBOSE
|
916
|
-
|
917
910
|
if RUBY_PLATFORM.match('linux')
|
918
911
|
require 'active_ldap/timeout'
|
919
912
|
else
|
@@ -942,14 +935,14 @@ require 'active_ldap/configuration'
|
|
942
935
|
require 'active_ldap/connection'
|
943
936
|
require 'active_ldap/attributes'
|
944
937
|
require 'active_ldap/object_class'
|
945
|
-
require 'active_ldap/
|
938
|
+
require 'active_ldap/distinguished_name'
|
946
939
|
|
947
940
|
require_gem_if_need.call("active_record/base", "activerecord")
|
948
941
|
require 'active_ldap/validations'
|
949
942
|
require 'active_ldap/callbacks'
|
950
943
|
|
951
944
|
module ActiveLdap
|
952
|
-
VERSION = "0.8.
|
945
|
+
VERSION = "0.8.2"
|
953
946
|
end
|
954
947
|
|
955
948
|
ActiveLdap::Base.class_eval do
|
@@ -962,4 +955,10 @@ ActiveLdap::Base.class_eval do
|
|
962
955
|
include ActiveLdap::Callbacks
|
963
956
|
end
|
964
957
|
|
965
|
-
|
958
|
+
unless defined?(ACTIVE_LDAP_CONNECTION_ADAPTERS)
|
959
|
+
ACTIVE_LDAP_CONNECTION_ADAPTERS = %w(ldap net_ldap)
|
960
|
+
end
|
961
|
+
|
962
|
+
ACTIVE_LDAP_CONNECTION_ADAPTERS.each do |adapter|
|
963
|
+
require "active_ldap/adapter/#{adapter}"
|
964
|
+
end
|