treequel 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +354 -0
- data/LICENSE +27 -0
- data/README +66 -0
- data/Rakefile +345 -0
- data/Rakefile.local +43 -0
- data/bin/treeirb +14 -0
- data/bin/treequel +229 -0
- data/examples/company-directory.rb +112 -0
- data/examples/ldap-monitor.rb +143 -0
- data/examples/ldap-monitor/public/css/master.css +328 -0
- data/examples/ldap-monitor/public/images/card_small.png +0 -0
- data/examples/ldap-monitor/public/images/chain_small.png +0 -0
- data/examples/ldap-monitor/public/images/globe_small.png +0 -0
- data/examples/ldap-monitor/public/images/globe_small_green.png +0 -0
- data/examples/ldap-monitor/public/images/plug.png +0 -0
- data/examples/ldap-monitor/public/images/shadows/large-30-down.png +0 -0
- data/examples/ldap-monitor/public/images/tick.png +0 -0
- data/examples/ldap-monitor/public/images/tick_circle.png +0 -0
- data/examples/ldap-monitor/public/images/treequel-favicon.png +0 -0
- data/examples/ldap-monitor/views/backends.erb +41 -0
- data/examples/ldap-monitor/views/connections.erb +74 -0
- data/examples/ldap-monitor/views/databases.erb +39 -0
- data/examples/ldap-monitor/views/dump_subsystem.erb +14 -0
- data/examples/ldap-monitor/views/index.erb +14 -0
- data/examples/ldap-monitor/views/layout.erb +35 -0
- data/examples/ldap-monitor/views/listeners.erb +30 -0
- data/examples/ldap_state.rb +62 -0
- data/lib/treequel.rb +145 -0
- data/lib/treequel/branch.rb +589 -0
- data/lib/treequel/branchcollection.rb +204 -0
- data/lib/treequel/branchset.rb +360 -0
- data/lib/treequel/constants.rb +604 -0
- data/lib/treequel/directory.rb +541 -0
- data/lib/treequel/exceptions.rb +32 -0
- data/lib/treequel/filter.rb +704 -0
- data/lib/treequel/mixins.rb +325 -0
- data/lib/treequel/schema.rb +245 -0
- data/lib/treequel/schema/attributetype.rb +252 -0
- data/lib/treequel/schema/ldapsyntax.rb +96 -0
- data/lib/treequel/schema/matchingrule.rb +124 -0
- data/lib/treequel/schema/matchingruleuse.rb +124 -0
- data/lib/treequel/schema/objectclass.rb +289 -0
- data/lib/treequel/sequel_integration.rb +26 -0
- data/lib/treequel/utils.rb +169 -0
- data/rake/191_compat.rb +26 -0
- data/rake/dependencies.rb +76 -0
- data/rake/helpers.rb +434 -0
- data/rake/hg.rb +261 -0
- data/rake/manual.rb +782 -0
- data/rake/packaging.rb +135 -0
- data/rake/publishing.rb +318 -0
- data/rake/rdoc.rb +30 -0
- data/rake/style.rb +62 -0
- data/rake/svn.rb +668 -0
- data/rake/testing.rb +187 -0
- data/rake/verifytask.rb +64 -0
- data/rake/win32.rb +190 -0
- data/spec/lib/constants.rb +93 -0
- data/spec/lib/helpers.rb +100 -0
- data/spec/treequel/branch_spec.rb +569 -0
- data/spec/treequel/branchcollection_spec.rb +213 -0
- data/spec/treequel/branchset_spec.rb +376 -0
- data/spec/treequel/directory_spec.rb +487 -0
- data/spec/treequel/filter_spec.rb +482 -0
- data/spec/treequel/mixins_spec.rb +330 -0
- data/spec/treequel/schema/attributetype_spec.rb +237 -0
- data/spec/treequel/schema/ldapsyntax_spec.rb +83 -0
- data/spec/treequel/schema/matchingrule_spec.rb +158 -0
- data/spec/treequel/schema/matchingruleuse_spec.rb +137 -0
- data/spec/treequel/schema/objectclass_spec.rb +262 -0
- data/spec/treequel/schema_spec.rb +118 -0
- data/spec/treequel/utils_spec.rb +49 -0
- data/spec/treequel_spec.rb +179 -0
- metadata +169 -0
@@ -0,0 +1,604 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'ldap'
|
4
|
+
require 'treequel'
|
5
|
+
|
6
|
+
|
7
|
+
### A collection of constants that are shared across the library
|
8
|
+
module Treequel::Constants
|
9
|
+
|
10
|
+
### Mapping of various symbolic names to LDAP integer LDAP_SCOPE_* values. Valid
|
11
|
+
### values are:
|
12
|
+
###
|
13
|
+
### :onelevel, :one, :base, :subtree, :sub
|
14
|
+
###
|
15
|
+
SCOPE = {
|
16
|
+
:onelevel => LDAP::LDAP_SCOPE_ONELEVEL,
|
17
|
+
:one => LDAP::LDAP_SCOPE_ONELEVEL,
|
18
|
+
:base => LDAP::LDAP_SCOPE_BASE,
|
19
|
+
:subtree => LDAP::LDAP_SCOPE_SUBTREE,
|
20
|
+
:sub => LDAP::LDAP_SCOPE_SUBTREE,
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
### Mapping of LDAP integer scope (LDAP_SCOPE_*) values to their names.
|
24
|
+
SCOPE_NAME = {
|
25
|
+
LDAP::LDAP_SCOPE_ONELEVEL => 'one',
|
26
|
+
LDAP::LDAP_SCOPE_BASE => 'base',
|
27
|
+
LDAP::LDAP_SCOPE_SUBTREE => 'subtree',
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
### OIDs of RFC values
|
32
|
+
module OIDS
|
33
|
+
|
34
|
+
# :stopdoc:
|
35
|
+
|
36
|
+
### Object Classes (from RFC 4519)
|
37
|
+
TOP_OBJECTCLASS = '2.5.6.0'
|
38
|
+
|
39
|
+
### Syntaxes (from RFC 4517)
|
40
|
+
RDN_SYNTAX = '1.2.36.79672281.1.5.0'
|
41
|
+
RFC2307_NIS_NETGROUP_TRIPLE_SYNTAX = '1.3.6.1.1.1.0.0'
|
42
|
+
RFC2307_BOOT_PARAMETER_SYNTAX = '1.3.6.1.1.1.0.1'
|
43
|
+
UUID_SYNTAX = '1.3.6.1.1.16.1'
|
44
|
+
AUDIO_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.4'
|
45
|
+
BINARY_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.5'
|
46
|
+
BIT_STRING_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.6'
|
47
|
+
BOOLEAN_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.7'
|
48
|
+
CERTIFICATE_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.8'
|
49
|
+
CERTIFICATE_LIST_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.9'
|
50
|
+
CERTIFICATE_PAIR_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.10'
|
51
|
+
COUNTRY_STRING_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.11'
|
52
|
+
DISTINGUISHED_NAME_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.12'
|
53
|
+
DELIVERY_METHOD_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.14'
|
54
|
+
DIRECTORY_STRING_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.15'
|
55
|
+
STRING_SYNTAX = DIRECTORY_STRING_SYNTAX # Alias
|
56
|
+
FACSIMILE_TELEPHONE_NUMBER_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.22'
|
57
|
+
GENERALIZED_TIME_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.24'
|
58
|
+
IA5_STRING_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.26'
|
59
|
+
INTEGER_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.27'
|
60
|
+
JPEG_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.28'
|
61
|
+
NAME_AND_OPTIONAL_UID_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.34'
|
62
|
+
NUMERIC_STRING_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.36'
|
63
|
+
OID_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.38'
|
64
|
+
OTHER_MAILBOX_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.39'
|
65
|
+
OCTET_STRING_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.40'
|
66
|
+
POSTAL_ADDRESS_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.41'
|
67
|
+
PRINTABLE_STRING_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.44'
|
68
|
+
SUBTREESPECIFICATION_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.45'
|
69
|
+
SUPPORTED_ALGORITHM_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.49'
|
70
|
+
TELEPHONE_NUMBER_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.50'
|
71
|
+
TELEX_NUMBER_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.52'
|
72
|
+
UTC_TIME_SYNTAX = '1.3.6.1.4.1.1466.115.121.1.53'
|
73
|
+
|
74
|
+
constants.each do |constname|
|
75
|
+
const_get( constname ).freeze
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
### A collection of Regexps to match various LDAP values
|
81
|
+
module Patterns
|
82
|
+
|
83
|
+
# :stopdoc:
|
84
|
+
|
85
|
+
# Schema-parsing patterns based on the BNF in
|
86
|
+
# RFC 4512 (http://tools.ietf.org/html/rfc4512#section-4.1.1)
|
87
|
+
|
88
|
+
# ALPHA = %x41-5A / %x61-7A ; "A"-"Z" / "a"-"z"
|
89
|
+
ALPHA = '[:alpha:]'
|
90
|
+
|
91
|
+
# LDIGIT = %x31-39 ; "1"-"9"
|
92
|
+
LDIGIT = '1-9'
|
93
|
+
|
94
|
+
# DIGIT = %x30 / LDIGIT ; "0"-"9"
|
95
|
+
DIGIT = '\d'
|
96
|
+
|
97
|
+
# HEX = DIGIT / %x41-46 / %x61-66 ; "0"-"9" / "A"-"F" / "a"-"f"
|
98
|
+
HEX = '[:xdigit:]'
|
99
|
+
|
100
|
+
#
|
101
|
+
# SP = 1*SPACE ; one or more " "
|
102
|
+
# WSP = 0*SPACE ; zero or more " "
|
103
|
+
SP = '[ ]+'
|
104
|
+
WSP = '[ ]*'
|
105
|
+
|
106
|
+
### These are inlined for simplicity
|
107
|
+
# NULL = %x00 ; null (0)
|
108
|
+
NULL = '\x00'
|
109
|
+
|
110
|
+
# SPACE = %x20 ; space (" ")
|
111
|
+
SPACE = '\x20'
|
112
|
+
|
113
|
+
# DQUOTE = %x22 ; quote (""")
|
114
|
+
DQUOTE = '\x22'
|
115
|
+
|
116
|
+
# SHARP = %x23 ; octothorpe (or sharp sign) ("#")
|
117
|
+
SHARP = '\x23'
|
118
|
+
|
119
|
+
# DOLLAR = %x24 ; dollar sign ("$")
|
120
|
+
DOLLAR = '\x24'
|
121
|
+
|
122
|
+
# SQUOTE = %x27 ; single quote ("'")
|
123
|
+
SQUOTE = '\x27'
|
124
|
+
|
125
|
+
# LPAREN = %x28 ; left paren ("(")
|
126
|
+
# RPAREN = %x29 ; right paren (")")
|
127
|
+
LPAREN = '\x28'
|
128
|
+
RPAREN = '\x29'
|
129
|
+
|
130
|
+
# PLUS = %x2B ; plus sign ("+")
|
131
|
+
PLUS = '\x2b'
|
132
|
+
|
133
|
+
# COMMA = %x2C ; comma (",")
|
134
|
+
COMMA = '\x2c'
|
135
|
+
|
136
|
+
# HYPHEN = %x2D ; hyphen ("-")
|
137
|
+
HYPHEN = '\x2d'
|
138
|
+
|
139
|
+
# DOT = %x2E ; period (".")
|
140
|
+
DOT = '\x2e'
|
141
|
+
|
142
|
+
# SEMI = %x3B ; semicolon (";")
|
143
|
+
SEMI = '\x3b'
|
144
|
+
|
145
|
+
# LANGLE = %x3C ; left angle bracket ("<")
|
146
|
+
# EQUALS = %x3D ; equals sign ("=")
|
147
|
+
# RANGLE = %x3E ; right angle bracket (">")
|
148
|
+
LANGLE = '\x3c'
|
149
|
+
EQUALS = '\x3d'
|
150
|
+
RANGLE = '\x3e'
|
151
|
+
|
152
|
+
# ESC = %x5C ; backslash ("\")
|
153
|
+
ESC = '\x5c'
|
154
|
+
|
155
|
+
# USCORE = %x5F ; underscore ("_")
|
156
|
+
USCORE = '\x5f'
|
157
|
+
|
158
|
+
# LCURLY = %x7B ; left curly brace "{"
|
159
|
+
# RCURLY = %x7D ; right curly brace "}"
|
160
|
+
LCURLY = '\x7b'
|
161
|
+
RCURLY = '\x7d'
|
162
|
+
|
163
|
+
# EXCLAMATION = %x21 ; exclamation mark ("!")
|
164
|
+
# AMPERSAND = %x26 ; ampersand (or AND symbol) ("&")
|
165
|
+
# ASTERISK = %x2A ; asterisk ("*")
|
166
|
+
# COLON = %x3A ; colon (":")
|
167
|
+
# VERTBAR = %x7C ; vertical bar (or pipe) ("|")
|
168
|
+
# TILDE = %x7E ; tilde ("~")
|
169
|
+
EXCLAMATION = '\x21'
|
170
|
+
AMPERSAND = '\x26'
|
171
|
+
ASTERISK = '\x2a'
|
172
|
+
COLON = '\x3a'
|
173
|
+
VERTBAR = '\x7c'
|
174
|
+
TILDE = '\x7e'
|
175
|
+
|
176
|
+
# ; Any UTF-8 [RFC3629] encoded Unicode [Unicode] character
|
177
|
+
# UTF0 = %x80-BF
|
178
|
+
# UTF1 = %x00-7F
|
179
|
+
# UTF2 = %xC2-DF UTF0
|
180
|
+
UTF0 = /[\x80-\xbf]/
|
181
|
+
UTF1 = /[\x00-\x7f]/
|
182
|
+
UTF2 = /[\xc2-\xdf] #{UTF0}/x
|
183
|
+
|
184
|
+
# UTF3 = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) / %xED %x80-9F UTF0 / %xEE-EF 2(UTF0)
|
185
|
+
UTF3 = /
|
186
|
+
\xe0 [\xa0-\xbf] #{UTF0}
|
187
|
+
|
|
188
|
+
[\xe1-\xec] #{UTF0}{2}
|
189
|
+
|
|
190
|
+
\xed [\x80-\x9f] #{UTF0}
|
191
|
+
|
|
192
|
+
[\xee-\xef] #{UTF0}{2}
|
193
|
+
/x
|
194
|
+
|
195
|
+
# UTF4 = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) / %xF4 %x80-8F 2(UTF0)
|
196
|
+
UTF4 = /
|
197
|
+
\xf0 [\x90-\xbf] #{UTF0}{2}
|
198
|
+
|
|
199
|
+
[\xf1-\xf3] #{UTF0}{3}
|
200
|
+
|
|
201
|
+
\xf4 [\x80-\x8f] #{UTF0}{2}
|
202
|
+
/x
|
203
|
+
|
204
|
+
# UTFMB = UTF2 / UTF3 / UTF4
|
205
|
+
UTFMB = Regexp.union( UTF2, UTF3, UTF4 )
|
206
|
+
|
207
|
+
# UTF8 = UTF1 / UTFMB
|
208
|
+
UTF8 = Regexp.union( UTF1, UTFMB )
|
209
|
+
|
210
|
+
# OCTET = %x00-FF ; Any octet (8-bit data unit)
|
211
|
+
OCTET = '.'
|
212
|
+
|
213
|
+
# leadkeychar = ALPHA
|
214
|
+
LEADKEYCHAR = /[#{ALPHA}]/
|
215
|
+
|
216
|
+
# keychar = ALPHA / DIGIT / HYPHEN
|
217
|
+
KEYCHAR = /[#{ALPHA}#{DIGIT}\-]/
|
218
|
+
|
219
|
+
# number = DIGIT / ( LDIGIT 1*DIGIT )
|
220
|
+
NUMBER = /[#{LDIGIT}]#{DIGIT}+|#{DIGIT}/ # Reversed for greediness
|
221
|
+
|
222
|
+
# keystring = leadkeychar *keychar
|
223
|
+
KEYSTRING = /#{LEADKEYCHAR}#{KEYCHAR}*/
|
224
|
+
|
225
|
+
# Object identifiers (OIDs) [X.680] are represented in LDAP using a
|
226
|
+
# dot-decimal format conforming to the ABNF:
|
227
|
+
|
228
|
+
# numericoid = number 1*( DOT number )
|
229
|
+
NUMERICOID = /#{NUMBER}(?: #{DOT} #{NUMBER} )+/x
|
230
|
+
|
231
|
+
|
232
|
+
# Short names, also known as ¨iptors, are used as more readable
|
233
|
+
# aliases for object identifiers. Short names are case insensitive and
|
234
|
+
# conform to the ABNF:
|
235
|
+
|
236
|
+
# descr = keystring
|
237
|
+
DESCR = KEYSTRING
|
238
|
+
|
239
|
+
# Where either an object identifier or a short name may be specified,
|
240
|
+
# the following production is used:
|
241
|
+
|
242
|
+
# oid = descr / numericoid
|
243
|
+
OID = / #{DESCR} | #{NUMERICOID} /x
|
244
|
+
|
245
|
+
|
246
|
+
# len = number
|
247
|
+
LEN = NUMBER
|
248
|
+
|
249
|
+
# noidlen = numericoid [ LCURLY len RCURLY ]
|
250
|
+
NOIDLEN = /#{NUMERICOID} (?:#{LCURLY} #{LEN} #{RCURLY})?/x
|
251
|
+
|
252
|
+
# oidlist = oid *( WSP DOLLAR WSP oid )
|
253
|
+
OIDLIST = /#{OID} (?: #{WSP} #{DOLLAR} #{WSP} #{OID} )*/x
|
254
|
+
|
255
|
+
# oids = oid / ( LPAREN WSP oidlist WSP RPAREN )
|
256
|
+
OIDS = / #{OID} | #{LPAREN} #{WSP} #{OIDLIST} #{WSP} #{RPAREN} /x
|
257
|
+
|
258
|
+
# xstring = "X" HYPHEN 1*( ALPHA / HYPHEN / USCORE )
|
259
|
+
XSTRING = / X #{HYPHEN} [#{ALPHA}#{HYPHEN}#{USCORE}]+ /x
|
260
|
+
|
261
|
+
# qdescr = SQUOTE descr SQUOTE
|
262
|
+
# qdescrlist = [ qdescr *( SP qdescr ) ]
|
263
|
+
# qdescrs = qdescr / ( LPAREN WSP qdescrlist WSP RPAREN )
|
264
|
+
QDESCR = / #{SQUOTE} #{DESCR} #{SQUOTE} /x
|
265
|
+
QDESCRLIST = /(?: #{QDESCR} (?: #{SP} #{QDESCR} )* )?/x
|
266
|
+
QDESCRS = / #{QDESCR} | #{LPAREN} #{WSP} #{QDESCRLIST} #{WSP} #{RPAREN} /x
|
267
|
+
|
268
|
+
# ; Any ASCII character except %x27 ("\'") and %x5C ("\")
|
269
|
+
# QUTF1 = %x00-26 / %x28-5B / %x5D-7F
|
270
|
+
QUTF1 = /[\x00-\x26\x28-\x5b\x5d-\x7f]/
|
271
|
+
|
272
|
+
# ; Any UTF-8 encoded Unicode character
|
273
|
+
# ; except %x27 ("\'") and %x5C ("\")
|
274
|
+
# QUTF8 = QUTF1 / UTFMB
|
275
|
+
QUTF8 = Regexp.union( QUTF1, UTFMB )
|
276
|
+
|
277
|
+
# QQ = ESC %x32 %x37 ; "\27"
|
278
|
+
# QS = ESC %x35 ( %x43 / %x63 ) ; "\5C" / "\5c"
|
279
|
+
QQ = / #{ESC} 27 /x
|
280
|
+
QS = / #{ESC} 5c /xi
|
281
|
+
|
282
|
+
|
283
|
+
### NOTE: QDSTRING is zero-or-more despite the RFC's specifying it as 1 or more
|
284
|
+
### to support empty DESC attributes in the wild (e.g., the ones in the
|
285
|
+
### attributeTypes from the 'retcode' overlay in OpenLDAP)
|
286
|
+
|
287
|
+
# dstring = 1*( QS / QQ / QUTF8 ) ; escaped UTF-8 string
|
288
|
+
# qdstring = SQUOTE dstring SQUOTE
|
289
|
+
# qdstringlist = [ qdstring *( SP qdstring ) ]
|
290
|
+
# qdstrings = qdstring / ( LPAREN WSP qdstringlist WSP RPAREN )
|
291
|
+
DSTRING = / (?: #{QS} | #{QQ} | #{QUTF8} )* /x
|
292
|
+
QDSTRING = / #{SQUOTE} #{DSTRING} #{SQUOTE} /x
|
293
|
+
QDSTRINGLIST = /(?: #{QDSTRING} (?: #{SP} #{QDSTRING} )* )?/x
|
294
|
+
QDSTRINGS = / #{QDSTRING} | #{LPAREN} #{WSP} #{QDSTRINGLIST} #{WSP} #{RPAREN} /x
|
295
|
+
|
296
|
+
# extensions = *( SP xstring SP qdstrings )
|
297
|
+
EXTENSIONS = /(?: #{SP} #{XSTRING} #{SP} #{QDSTRINGS} )*/x
|
298
|
+
|
299
|
+
# kind = "ABSTRACT" / "STRUCTURAL" / "AUXILIARY"
|
300
|
+
KIND = Regexp.union( 'ABSTRACT', 'STRUCTURAL', 'AUXILIARY' )
|
301
|
+
|
302
|
+
# Object Class definitions are written according to the ABNF:
|
303
|
+
|
304
|
+
# ObjectClassDescription = LPAREN WSP
|
305
|
+
# numericoid ; object identifier
|
306
|
+
# [ SP "NAME" SP qdescrs ] ; short names (descriptors)
|
307
|
+
# [ SP "DESC" SP qdstring ] ; description
|
308
|
+
# [ SP "OBSOLETE" ] ; not active
|
309
|
+
# [ SP "SUP" SP oids ] ; superior object classes
|
310
|
+
# [ SP kind ] ; kind of class
|
311
|
+
# [ SP "MUST" SP oids ] ; attribute types
|
312
|
+
# [ SP "MAY" SP oids ] ; attribute types
|
313
|
+
# extensions WSP RPAREN
|
314
|
+
|
315
|
+
LDAP_OBJECTCLASS_DESCRIPTION = %r{
|
316
|
+
#{LPAREN} #{WSP}
|
317
|
+
(#{NUMERICOID}) # $1 = oid
|
318
|
+
(?:#{SP} NAME #{SP} (#{QDESCRS}) )? # $2 = name
|
319
|
+
(?:#{SP} DESC #{SP} (#{QDSTRING}))? # $3 = desc
|
320
|
+
(?:#{SP} (OBSOLETE) )? # $4 = obsolete
|
321
|
+
(?:#{SP} SUP #{SP} (#{OIDS}) )? # $5 = sup
|
322
|
+
(?:#{SP} (#{KIND}) )? # $6 = kind
|
323
|
+
(?:#{SP} MUST #{SP} (#{OIDS}) )? # $7 = must attrs
|
324
|
+
(?:#{SP} MAY #{SP} (#{OIDS}) )? # $8 = may attrs
|
325
|
+
(#{EXTENSIONS}) # $9 = extensions
|
326
|
+
#{WSP} #{RPAREN}
|
327
|
+
}x
|
328
|
+
|
329
|
+
|
330
|
+
# usage = "userApplications" / ; user
|
331
|
+
# "directoryOperation" / ; directory operational
|
332
|
+
# "distributedOperation" / ; DSA-shared operational
|
333
|
+
# "dSAOperation" ; DSA-specific operational
|
334
|
+
USAGE = Regexp.union(
|
335
|
+
'userApplications',
|
336
|
+
'directoryOperation',
|
337
|
+
'distributedOperation',
|
338
|
+
'dSAOperation'
|
339
|
+
)
|
340
|
+
|
341
|
+
# Attribute Type definitions are written according to the ABNF:
|
342
|
+
#
|
343
|
+
# AttributeTypeDescription = LPAREN WSP
|
344
|
+
# numericoid ; object identifier
|
345
|
+
# [ SP "NAME" SP qdescrs ] ; short names (descriptors)
|
346
|
+
# [ SP "DESC" SP qdstring ] ; description
|
347
|
+
# [ SP "OBSOLETE" ] ; not active
|
348
|
+
# [ SP "SUP" SP oid ] ; supertype
|
349
|
+
# [ SP "EQUALITY" SP oid ] ; equality matching rule
|
350
|
+
# [ SP "ORDERING" SP oid ] ; ordering matching rule
|
351
|
+
# [ SP "SUBSTR" SP oid ] ; substrings matching rule
|
352
|
+
# [ SP "SYNTAX" SP noidlen ] ; value syntax
|
353
|
+
# [ SP "SINGLE-VALUE" ] ; single-value
|
354
|
+
# [ SP "COLLECTIVE" ] ; collective
|
355
|
+
# [ SP "NO-USER-MODIFICATION" ] ; not user modifiable
|
356
|
+
# [ SP "USAGE" SP usage ] ; usage
|
357
|
+
# extensions WSP RPAREN ; extensions
|
358
|
+
LDAP_ATTRIBUTE_TYPE_DESCRIPTION = %r{
|
359
|
+
#{LPAREN} #{WSP}
|
360
|
+
(#{NUMERICOID}) # $1 = oid
|
361
|
+
(?:#{SP} NAME #{SP} (#{QDESCRS}) )? # $2 = name
|
362
|
+
(?:#{SP} DESC #{SP} (#{QDSTRING}) )? # $3 = description
|
363
|
+
(?:#{SP} (OBSOLETE) )? # $4 = obsolete flag
|
364
|
+
(?:#{SP} SUP #{SP} (#{OID}) )? # $5 = superior type oid
|
365
|
+
(?:#{SP} EQUALITY #{SP} (#{OID}) )? # $6 = equality matching rule oid
|
366
|
+
(?:#{SP} ORDERING #{SP} (#{OID}) )? # $7 = ordering matching rule oid
|
367
|
+
(?:#{SP} SUBSTR #{SP} (#{OID}) )? # $8 = substring matching rule oid
|
368
|
+
(?:#{SP} SYNTAX #{SP} (#{NOIDLEN}) )? # $9 = value syntax matching oid
|
369
|
+
(?:#{SP} (SINGLE-VALUE) )? # $10 = single value flag
|
370
|
+
(?:#{SP} (COLLECTIVE) )? # $11 = collective flag
|
371
|
+
(?:#{SP} (NO-USER-MODIFICATION) )? # $12 = no user modification flag
|
372
|
+
(?:#{SP} USAGE #{SP} (#{USAGE}) )? # $13 = usage type
|
373
|
+
(#{EXTENSIONS}) # $14 = extensions
|
374
|
+
#{WSP} #{RPAREN}
|
375
|
+
}x
|
376
|
+
|
377
|
+
|
378
|
+
# MatchingRuleDescription = LPAREN WSP
|
379
|
+
# numericoid ; object identifier
|
380
|
+
# [ SP "NAME" SP qdescrs ] ; short names (descriptors)
|
381
|
+
# [ SP "DESC" SP qdstring ] ; description
|
382
|
+
# [ SP "OBSOLETE" ] ; not active
|
383
|
+
# SP "SYNTAX" SP numericoid ; assertion syntax
|
384
|
+
# extensions WSP RPAREN ; extensions
|
385
|
+
LDAP_MATCHING_RULE_DESCRIPTION = %r{
|
386
|
+
#{LPAREN} #{WSP}
|
387
|
+
(#{NUMERICOID}) # $1 = oid
|
388
|
+
(?:#{SP} NAME #{SP} (#{QDESCRS}) )? # $2 = name
|
389
|
+
(?:#{SP} DESC #{SP} (#{QDSTRING}) )? # $3 = description
|
390
|
+
(?:#{SP} (OBSOLETE) )? # $4 = obsolete flag
|
391
|
+
#{SP} SYNTAX #{SP} (#{NUMERICOID}) # $5 = syntax numeric OID
|
392
|
+
(#{EXTENSIONS}) # $6 = extensions
|
393
|
+
#{WSP} #{RPAREN}
|
394
|
+
}x
|
395
|
+
|
396
|
+
|
397
|
+
# Matching rule use descriptions are written according to the following
|
398
|
+
# ABNF:
|
399
|
+
#
|
400
|
+
# MatchingRuleUseDescription = LPAREN WSP
|
401
|
+
# numericoid ; object identifier
|
402
|
+
# [ SP "NAME" SP qdescrs ] ; short names (descriptors)
|
403
|
+
# [ SP "DESC" SP qdstring ] ; description
|
404
|
+
# [ SP "OBSOLETE" ] ; not active
|
405
|
+
# SP "APPLIES" SP oids ; attribute types
|
406
|
+
# extensions WSP RPAREN ; extensions
|
407
|
+
LDAP_MATCHING_RULE_USE_DESCRIPTION = %r{
|
408
|
+
#{LPAREN} #{WSP}
|
409
|
+
(#{NUMERICOID}) # $1 = oid
|
410
|
+
(?:#{SP} NAME #{SP} (#{QDESCRS}) )? # $2 = name
|
411
|
+
(?:#{SP} DESC #{SP} (#{QDSTRING}) )? # $3 = description
|
412
|
+
(?:#{SP} (OBSOLETE) )? # $4 = obsolete flag
|
413
|
+
#{SP} APPLIES #{SP} (#{OIDS}) # $5 = attribute types
|
414
|
+
(#{EXTENSIONS}) # $6 = extensions
|
415
|
+
#{WSP} #{RPAREN}
|
416
|
+
}x
|
417
|
+
|
418
|
+
|
419
|
+
# LDAP syntax definitions are written according to the ABNF:
|
420
|
+
#
|
421
|
+
# SyntaxDescription = LPAREN WSP
|
422
|
+
# numericoid ; object identifier
|
423
|
+
# [ SP "DESC" SP qdstring ] ; description
|
424
|
+
# extensions WSP RPAREN ; extensions
|
425
|
+
#
|
426
|
+
LDAP_SYNTAX_DESCRIPTION = %r{
|
427
|
+
#{LPAREN} #{WSP}
|
428
|
+
(#{NUMERICOID}) # $1 = oid
|
429
|
+
(?:#{SP} DESC #{SP} (#{QDSTRING}) )? # $2 = description
|
430
|
+
(#{EXTENSIONS}) # $3 = extensions
|
431
|
+
#{WSP} #{RPAREN}
|
432
|
+
}x
|
433
|
+
|
434
|
+
|
435
|
+
# UTF1SUBSET = %x01-27 / %x2B-5B / %x5D-7F
|
436
|
+
# ; UTF1SUBSET excludes 0x00 (NUL), LPAREN,
|
437
|
+
# ; RPAREN, ASTERISK, and ESC.
|
438
|
+
UTF1SUBSET = %r{
|
439
|
+
[\x01-\x27\x2b-\x5b\x50-\x7f]
|
440
|
+
}x
|
441
|
+
|
442
|
+
# normal = UTF1SUBSET / UTFMB
|
443
|
+
NORMAL = %r{ #{UTF1SUBSET} | #{UTFMB} }x
|
444
|
+
|
445
|
+
# escaped = ESC HEX HEX
|
446
|
+
ESCAPED = %r{ #{ESC} [[:xdigit:]]{2} }x
|
447
|
+
|
448
|
+
# valueencoding = 0*(normal / escaped)
|
449
|
+
VALUEENCODING = %r{ (?:#{NORMAL} | #{ESCAPED})* }x
|
450
|
+
|
451
|
+
# assertionvalue = valueencoding
|
452
|
+
# ; The <valueencoding> rule is used to encode an <AssertionValue>
|
453
|
+
# ; from Section 4.1.6 of [RFC4511].
|
454
|
+
ASSERTIONVALUE = VALUEENCODING
|
455
|
+
|
456
|
+
# The value part of a substring filter
|
457
|
+
# initial = assertionvalue
|
458
|
+
# any = ASTERISK *(assertionvalue ASTERISK)
|
459
|
+
# final = assertionvalue
|
460
|
+
LDAP_SUBSTRING_FILTER_VALUE = %r{
|
461
|
+
#{ASSERTIONVALUE}
|
462
|
+
#{ASTERISK}
|
463
|
+
(?: #{ASSERTIONVALUE} #{ASTERISK} )*
|
464
|
+
#{ASSERTIONVALUE}
|
465
|
+
}x
|
466
|
+
|
467
|
+
# An AttributeDescription (same as LDAPString)
|
468
|
+
# attributedescription = attributetype options
|
469
|
+
# attributetype = oid
|
470
|
+
# options = *( SEMI option )
|
471
|
+
# option = 1*keychar
|
472
|
+
LDAP_ATTRIBUTE_DESCRIPTION = %r{
|
473
|
+
(#{OID}) # $1: the OID
|
474
|
+
( # $2: attribute options
|
475
|
+
(?:;#{KEYCHAR}+)*
|
476
|
+
)
|
477
|
+
}x
|
478
|
+
|
479
|
+
# A substring filter, from RFC4511, section 4.5.1
|
480
|
+
# SubstringFilter ::= SEQUENCE {
|
481
|
+
# type AttributeDescription,
|
482
|
+
# substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE {
|
483
|
+
# initial [0] AssertionValue, -- can occur at most once
|
484
|
+
# any [1] AssertionValue,
|
485
|
+
# final [2] AssertionValue } -- can occur at most once
|
486
|
+
# }
|
487
|
+
LDAP_SUBSTRING_FILTER = %r{
|
488
|
+
(#{LDAP_ATTRIBUTE_DESCRIPTION}) # $1: AttributeDescription
|
489
|
+
=
|
490
|
+
(#{LDAP_SUBSTRING_FILTER_VALUE}) # $2: value
|
491
|
+
}x
|
492
|
+
|
493
|
+
|
494
|
+
#
|
495
|
+
# Distinguished Names (RFC4514)
|
496
|
+
#
|
497
|
+
|
498
|
+
# hexpair = HEX HEX
|
499
|
+
HEXPAIR = /#{HEX}{2}/
|
500
|
+
|
501
|
+
# hexstring = SHARP 1*hexpair
|
502
|
+
HEXSTRING = %r{ #{SHARP} #{HEXPAIR}+ }x
|
503
|
+
|
504
|
+
# escaped = DQUOTE / PLUS / COMMA / SEMI / LANGLE / RANGLE
|
505
|
+
DN_ESCAPED = %r{ #{DQUOTE} | #{PLUS} | #{COMMA} | #{SEMI} | #{LANGLE} | #{RANGLE} }x
|
506
|
+
|
507
|
+
# special = escaped / SPACE / SHARP / EQUALS
|
508
|
+
SPECIAL = %r{ #{DN_ESCAPED} | #{SPACE} | #{SHARP} | #{EQUALS} }x
|
509
|
+
|
510
|
+
# pair = ESC ( ESC / special / hexpair )
|
511
|
+
PAIR = %r{
|
512
|
+
#{ESC}
|
513
|
+
(?:
|
514
|
+
#{ESC}
|
515
|
+
| #{SPECIAL}
|
516
|
+
| #{HEXPAIR}
|
517
|
+
)
|
518
|
+
}x
|
519
|
+
|
520
|
+
# SUTF1 = %x01-21 / %x23-2A / %x2D-3A / %x3D / %x3F-5B / %x5D-7F
|
521
|
+
SUTF1 = /[\x01-\x21\x23-\x2a\x2d-\x3a\x3d\x3f-\x5b\x5d-\x7f]/
|
522
|
+
|
523
|
+
# stringchar = SUTF1 / UTFMB
|
524
|
+
STRINGCHAR = %r{ #{SUTF1} | #{UTFMB} }x
|
525
|
+
|
526
|
+
# TUTF1 = %x01-1F / %x21 / %x23-2A / %x2D-3A / %x3D / %x3F-5B / %x5D-7F
|
527
|
+
TUTF1 = /[\x01-\x1f\x21\x23-\x2a\x2d-\x3a\x3d\x3f-\x5b\x5d-\x7f]/
|
528
|
+
|
529
|
+
# trailchar = TUTF1 / UTFMB
|
530
|
+
TRAILCHAR = %r{ #{TUTF1} | #{UTFMB} }x
|
531
|
+
|
532
|
+
# LUTF1 = %x01-1F / %x21 / %x24-2A / %x2D-3A / %x3D / %x3F-5B / %x5D-7F
|
533
|
+
LUTF1 = /[\x01-\x1f\x21\x24-\x2a\x2d-\x3a\x3d\x3f-\x5b\x5d-\x7f]/
|
534
|
+
|
535
|
+
# leadchar = LUTF1 / UTFMB
|
536
|
+
LEADCHAR = %r{ #{LUTF1} | #{UTFMB} }x
|
537
|
+
|
538
|
+
# ; The following characters are to be escaped when they appear
|
539
|
+
# ; in the value to be encoded: ESC, one of <escaped>, leading
|
540
|
+
# ; SHARP or SPACE, trailing SPACE, and NULL.
|
541
|
+
# string = [ ( leadchar / pair ) [ *( stringchar / pair )
|
542
|
+
# ( trailchar / pair ) ] ]
|
543
|
+
# NOTE: the RFC specifies that all characters are optional in a STRING, which means that
|
544
|
+
# the RDN 'cn=' is valid. While I hesitate to deviate from the RFC, I can't currently
|
545
|
+
# conceive of a way such an RDN would be useful, so I'm defining this as requiring at
|
546
|
+
# least one character. If this becomes a problem later, we can just surround it
|
547
|
+
# with non-capturing parens with a optional qualifier.
|
548
|
+
STRING = %r{
|
549
|
+
(?:
|
550
|
+
#{LEADCHAR}
|
551
|
+
| #{PAIR}
|
552
|
+
)
|
553
|
+
(?:
|
554
|
+
(?: #{STRINGCHAR} | #{PAIR} )*
|
555
|
+
#{TRAILCHAR} | #{PAIR}
|
556
|
+
)?
|
557
|
+
}x
|
558
|
+
|
559
|
+
# attributeValue = string / hexstring
|
560
|
+
ATTRIBUTE_VALUE = %r{
|
561
|
+
#{HEXSTRING} # Since STRING can match the empty string, try HEXSTRING first
|
562
|
+
| #{STRING}
|
563
|
+
}x
|
564
|
+
|
565
|
+
# attributeType = descr / numericoid
|
566
|
+
ATTRIBUTE_TYPE = %r{
|
567
|
+
#{DESCR}
|
568
|
+
|
|
569
|
+
#{NUMERICOID}
|
570
|
+
}x
|
571
|
+
|
572
|
+
# attributeTypeAndValue = attributeType EQUALS attributeValue
|
573
|
+
ATTRIBUTE_TYPE_AND_VALUE = %r{
|
574
|
+
#{ATTRIBUTE_TYPE} = #{ATTRIBUTE_VALUE}
|
575
|
+
}x
|
576
|
+
|
577
|
+
# relativeDistinguishedName = attributeTypeAndValue
|
578
|
+
# *( PLUS attributeTypeAndValue )
|
579
|
+
RELATIVE_DISTINGUISHED_NAME = %r{
|
580
|
+
#{ATTRIBUTE_TYPE_AND_VALUE}
|
581
|
+
(?:
|
582
|
+
\+
|
583
|
+
#{ATTRIBUTE_TYPE_AND_VALUE}
|
584
|
+
)*
|
585
|
+
}x
|
586
|
+
|
587
|
+
# distinguishedName = [ relativeDistinguishedName
|
588
|
+
# *( COMMA relativeDistinguishedName ) ]
|
589
|
+
DISTINGUISHED_NAME = %r{
|
590
|
+
#{RELATIVE_DISTINGUISHED_NAME}
|
591
|
+
(?:
|
592
|
+
,
|
593
|
+
#{RELATIVE_DISTINGUISHED_NAME}
|
594
|
+
)*
|
595
|
+
}x
|
596
|
+
|
597
|
+
|
598
|
+
end # module Patterns
|
599
|
+
|
600
|
+
end # module Treequel::Constants
|
601
|
+
|
602
|
+
# vim: set nosta noet ts=4 sw=4:
|
603
|
+
|
604
|
+
|