ruby-activeldap-debug 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/activeldap/associations.rb +122 -0
- data/lib/activeldap/base.rb +1244 -0
- data/lib/activeldap/configuration.rb +25 -0
- data/lib/activeldap/schema2.rb +210 -0
- data/lib/activeldap.rb +916 -0
- metadata +54 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
module ActiveLDAP
|
3
|
+
# Configuration
|
4
|
+
#
|
5
|
+
# Configuration provides the default settings required for
|
6
|
+
# ActiveLDAP to work with your LDAP server. All of these
|
7
|
+
# settings can be passed in at initialization time.
|
8
|
+
module Configuration
|
9
|
+
@@host = "127.0.0.1"
|
10
|
+
@@port = 389
|
11
|
+
@@bind_format = "uid=%s,ou=People,dc=example,dc=com"
|
12
|
+
|
13
|
+
# Make the return value the string that is your LDAP base
|
14
|
+
def Base.base
|
15
|
+
'dc=example,dc=com'
|
16
|
+
end
|
17
|
+
|
18
|
+
# This is optionally set to the array of objectClass names
|
19
|
+
# that are minimally required for EVERY object on your LDAP server.
|
20
|
+
# If you don't want one, set this to [].
|
21
|
+
def Base.required_classes
|
22
|
+
['top']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'ldap'
|
2
|
+
require 'ldap/schema'
|
3
|
+
|
4
|
+
module LDAP
|
5
|
+
class Schema2 < Schema
|
6
|
+
@@attr_cache = {}
|
7
|
+
@@class_cache = {}
|
8
|
+
|
9
|
+
# attr
|
10
|
+
#
|
11
|
+
# This is just like LDAP::Schema#attr except that it allows
|
12
|
+
# look up in any of the given keys.
|
13
|
+
# e.g.
|
14
|
+
# attr('attributeTypes', 'cn', 'DESC')
|
15
|
+
# attr('ldapSyntaxes', '1.3.6.1.4.1.1466.115.121.1.5', 'DESC')
|
16
|
+
def attr(sub, type, at)
|
17
|
+
return '' if sub.empty?
|
18
|
+
return '' if type.empty?
|
19
|
+
return '' if at.empty?
|
20
|
+
|
21
|
+
# Check already parsed options first
|
22
|
+
if @@attr_cache.has_key? sub \
|
23
|
+
and @@attr_cache[sub].has_key? type \
|
24
|
+
and @@attr_cache[sub][type].has_key? at
|
25
|
+
return @@attr_cache[sub][type][at].dup
|
26
|
+
end
|
27
|
+
|
28
|
+
# Initialize anything that is required
|
29
|
+
unless @@attr_cache.has_key? sub
|
30
|
+
@@attr_cache[sub] = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
unless @@attr_cache[sub].has_key? type
|
34
|
+
@@attr_cache[sub][type] = {}
|
35
|
+
end
|
36
|
+
|
37
|
+
at = at.upcase
|
38
|
+
self[sub].each do |s|
|
39
|
+
line = ''
|
40
|
+
if type[0..0] =~ /[0-9]/
|
41
|
+
line = s if s =~ /\(\s+#{type}\s+(?:[A-Z]|\))/
|
42
|
+
else
|
43
|
+
line = s if s =~ /NAME\s+\(?.*'#{type}'.*\)?\s+(?:[A-Z]|\))/
|
44
|
+
end
|
45
|
+
|
46
|
+
# I need to check, but I think some of these matchs
|
47
|
+
# overlap. I'll need to check these when I'm less sleepy.
|
48
|
+
multi = ''
|
49
|
+
case line
|
50
|
+
when /#{at}\s+[\)A-Z]/
|
51
|
+
@@attr_cache[sub][type][at] = ['TRUE']
|
52
|
+
return ['TRUE']
|
53
|
+
when /#{at}\s+'(.+?)'/
|
54
|
+
@@attr_cache[sub][type][at] = [$1]
|
55
|
+
return [$1]
|
56
|
+
when /#{at}\s+\((.+?)\)/
|
57
|
+
multi = $1
|
58
|
+
when /#{at}\s+\(([\w\d\s\.]+)\)/
|
59
|
+
multi = $1
|
60
|
+
when /#{at}\s+([\w\d\.]+)/
|
61
|
+
@@attr_cache[sub][type][at] = [$1]
|
62
|
+
return [$1]
|
63
|
+
end
|
64
|
+
# Split up multiple matches
|
65
|
+
# if oc then it is sep'd by $
|
66
|
+
# if attr then bu spaces
|
67
|
+
if multi.match(/\$/)
|
68
|
+
@@attr_cache[sub][type][at] = multi.split("$").collect{|attr| attr.strip}
|
69
|
+
return @@attr_cache[sub][type][at].dup
|
70
|
+
elsif not multi.empty?
|
71
|
+
@@attr_cache[sub][type][at] = multi.gsub(/'/, '').split(' ').collect{|attr| attr.strip}
|
72
|
+
return @@attr_cache[sub][type][at].dup
|
73
|
+
end
|
74
|
+
end
|
75
|
+
@@attr_cache[sub][type][at] = []
|
76
|
+
return []
|
77
|
+
end
|
78
|
+
|
79
|
+
# attribute_aliases
|
80
|
+
#
|
81
|
+
# Returns all names from the LDAP schema for the
|
82
|
+
# attribute given.
|
83
|
+
def attribute_aliases(attr)
|
84
|
+
attr('attributeTypes', attr, 'NAME')
|
85
|
+
end # attribute aliases
|
86
|
+
|
87
|
+
# read_only?
|
88
|
+
#
|
89
|
+
# Returns true if an attribute is read-only
|
90
|
+
# NO-USER-MODIFICATION
|
91
|
+
def read_only?(attr)
|
92
|
+
result = attr('attributeTypes', attr, 'NO-USER-MODIFICATION')
|
93
|
+
return true if result[0] == 'TRUE'
|
94
|
+
return false
|
95
|
+
end
|
96
|
+
|
97
|
+
# single_value?
|
98
|
+
#
|
99
|
+
# Returns true if an attribute can only have one
|
100
|
+
# value defined
|
101
|
+
# SINGLE-VALUE
|
102
|
+
def single_value?(attr)
|
103
|
+
result = attr('attributeTypes', attr, 'SINGLE-VALUE')
|
104
|
+
return true if result[0] == 'TRUE'
|
105
|
+
return false
|
106
|
+
end
|
107
|
+
|
108
|
+
# binary?
|
109
|
+
#
|
110
|
+
# Returns true if the given attribute's syntax
|
111
|
+
# is X-NOT-HUMAN-READABLE or X-BINARY-TRANSFER-REQUIRED
|
112
|
+
def binary?(attr)
|
113
|
+
# Get syntax OID
|
114
|
+
syntax = attr('attributeTypes', attr, 'SYNTAX')
|
115
|
+
return false if syntax.empty?
|
116
|
+
|
117
|
+
# This seems to indicate binary
|
118
|
+
result = attr('ldapSyntaxes', syntax[0], 'X-NOT-HUMAN-READABLE')
|
119
|
+
return true if result[0] == "TRUE"
|
120
|
+
|
121
|
+
# Get if binary transfer is required (non-binary types)
|
122
|
+
# Usually these have the above tag
|
123
|
+
result = attr('ldapSyntaxes', syntax[0], 'X-BINARY-TRANSFER-REQUIRED')
|
124
|
+
return true if result[0] == "TRUE"
|
125
|
+
|
126
|
+
return false
|
127
|
+
end # binary?
|
128
|
+
|
129
|
+
# binary_required?
|
130
|
+
#
|
131
|
+
# Returns true if the value MUST be transferred in binary
|
132
|
+
def binary_required?(attr)
|
133
|
+
# Get syntax OID
|
134
|
+
syntax = attr('attributeTypes', attr, 'SYNTAX')
|
135
|
+
return false if syntax.empty?
|
136
|
+
|
137
|
+
# Get if binary transfer is required (non-binary types)
|
138
|
+
# Usually these have the above tag
|
139
|
+
result = attr('ldapSyntaxes', syntax[0], 'X-BINARY-TRANSFER-REQUIRED')
|
140
|
+
return true if result[0] == "TRUE"
|
141
|
+
|
142
|
+
return false
|
143
|
+
end # binary_required?
|
144
|
+
|
145
|
+
# class_attributes
|
146
|
+
#
|
147
|
+
# Returns an Array of all the valid attributes (but not with full aliases)
|
148
|
+
# for the given objectClass
|
149
|
+
def class_attributes(objc)
|
150
|
+
if @@class_cache.has_key? objc
|
151
|
+
return @@class_cache[objc]
|
152
|
+
end
|
153
|
+
|
154
|
+
# Setup the cache
|
155
|
+
@@class_cache[objc] = {}
|
156
|
+
|
157
|
+
# First get all the current level attributes
|
158
|
+
@@class_cache[objc] = {:must => attr('objectClasses', objc, 'MUST'),
|
159
|
+
:may => attr('objectClasses', objc, 'MAY')}
|
160
|
+
|
161
|
+
# Now add all attributes from the parent object (SUPerclasses)
|
162
|
+
# Hopefully an iterative approach will be pretty speedy
|
163
|
+
# 1. build complete list of SUPs
|
164
|
+
# 2. Add attributes from each
|
165
|
+
sups = attr('objectClasses', objc, 'SUP')
|
166
|
+
loop do
|
167
|
+
start_size = sups.size
|
168
|
+
new_sups = []
|
169
|
+
sups.each do |sup|
|
170
|
+
new_sups += attr('objectClasses', sup, 'SUP')
|
171
|
+
end
|
172
|
+
sups += new_sups
|
173
|
+
sups.uniq!
|
174
|
+
break if sups.size == start_size
|
175
|
+
end
|
176
|
+
sups.each do |sup|
|
177
|
+
@@class_cache[objc][:must] += attr('objectClasses', sup, 'MUST')
|
178
|
+
@@class_cache[objc][:may] += attr('objectClasses', sup, 'MAY')
|
179
|
+
end
|
180
|
+
|
181
|
+
# Clean out the dupes.
|
182
|
+
@@class_cache[objc][:must].uniq!
|
183
|
+
@@class_cache[objc][:may].uniq!
|
184
|
+
|
185
|
+
# Return the cached value
|
186
|
+
return @@class_cache[objc].dup
|
187
|
+
end
|
188
|
+
|
189
|
+
end # Schema2
|
190
|
+
|
191
|
+
class Conn
|
192
|
+
def schema(base = nil, attrs = nil, sec = 0, usec = 0)
|
193
|
+
attrs ||= [
|
194
|
+
'objectClasses',
|
195
|
+
'attributeTypes',
|
196
|
+
'matchingRules',
|
197
|
+
'matchingRuleUse',
|
198
|
+
'dITStructureRules',
|
199
|
+
'dITContentRules',
|
200
|
+
'nameForms',
|
201
|
+
'ldapSyntaxes',
|
202
|
+
]
|
203
|
+
base ||= root_dse(['subschemaSubentry'], sec, usec)[0]['subschemaSubentry'][0]
|
204
|
+
base ||= 'cn=schema'
|
205
|
+
ent = search2(base, LDAP_SCOPE_BASE, '(objectClass=subschema)',
|
206
|
+
attrs, false, sec, usec)
|
207
|
+
return Schema2.new(ent[0])
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end # end LDAP
|