ruby-ldap 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +24 -0
- data/ChangeLog +762 -0
- data/FAQ +62 -0
- data/NOTES +77 -0
- data/README +266 -0
- data/TODO +15 -0
- data/conn.c +1810 -0
- data/entry.c +215 -0
- data/extconf.rb +268 -0
- data/ldap.c +577 -0
- data/lib/ldap/control.rb +50 -0
- data/lib/ldap/ldif.rb +569 -0
- data/lib/ldap/schema.rb +129 -0
- data/misc.c +512 -0
- data/mod.c +355 -0
- data/rbldap.h +194 -0
- data/saslconn.c +176 -0
- data/sslconn.c +377 -0
- data/test/add.rb +31 -0
- data/test/add2.rb +31 -0
- data/test/add3.rb +33 -0
- data/test/bind-ldaps.rb +25 -0
- data/test/bind-sasl.rb +17 -0
- data/test/bind-ssl.rb +25 -0
- data/test/bind.rb +34 -0
- data/test/compare.rb +17 -0
- data/test/conf.rb +12 -0
- data/test/delete.rb +13 -0
- data/test/ext.rb +49 -0
- data/test/misc1.rb +49 -0
- data/test/misc2.rb +40 -0
- data/test/modrdn.rb +23 -0
- data/test/search.rb +20 -0
- data/test/search2.rb +34 -0
- data/test/search3.rb +23 -0
- data/test/setup.rb +38 -0
- data/test/subschema.rb +21 -0
- data/test/tc_conn.rb +124 -0
- data/test/tc_ldif.rb +174 -0
- data/test/tc_schema.rb +32 -0
- data/test/tc_search.rb +137 -0
- data/test/ts_ldap.rb +8 -0
- data/win/winlber.h +21 -0
- data/win/winldap.h +324 -0
- metadata +100 -0
data/test/search3.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
# This file is a part of test scripts of LDAP extension module.
|
3
|
+
|
4
|
+
$test = File.dirname($0)
|
5
|
+
require "#{$test}/conf"
|
6
|
+
require "./ldap"
|
7
|
+
|
8
|
+
$KCODE = "UTF8"
|
9
|
+
|
10
|
+
conn = LDAP::Conn.new($HOST, $PORT)
|
11
|
+
conn.perror("bind")
|
12
|
+
conn.bind{
|
13
|
+
# search2 returns an array of hash
|
14
|
+
print("search2 without a block:\n")
|
15
|
+
conn.search2("dc=localhost, dc=localdomain", LDAP::LDAP_SCOPE_SUBTREE,
|
16
|
+
"(objectclass=*)", nil, false, 0, 0).each{|ent|
|
17
|
+
ent.each{|attr,vals|
|
18
|
+
print("#{attr}: #{vals.join(', ')}\n")
|
19
|
+
}
|
20
|
+
print("\n")
|
21
|
+
}
|
22
|
+
GC.start()
|
23
|
+
}
|
data/test/setup.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# $Id: setup.rb,v 1.3 2005/03/13 10:10:56 ianmacd Exp $
|
2
|
+
#
|
3
|
+
# Basic set-up for performing LDAP unit tests.
|
4
|
+
|
5
|
+
require 'ldap'
|
6
|
+
require 'ldap/schema'
|
7
|
+
require 'test/unit'
|
8
|
+
|
9
|
+
class TC_LDAPTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
@@conn = nil
|
12
|
+
|
13
|
+
# Get the LDAP host and base DN from /etc/ldap.conf.
|
14
|
+
def setup
|
15
|
+
unless @@conn && @@conn.bound?
|
16
|
+
File.open( '/etc/ldap.conf' ) do |f|
|
17
|
+
while line = f.gets
|
18
|
+
if line =~ /^host\s+(\S+)$/
|
19
|
+
@@host = $1
|
20
|
+
break
|
21
|
+
elsif line =~ /^base\s+(\S+)$/
|
22
|
+
@@base = $1
|
23
|
+
break
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
@@conn = LDAP::Conn.new( @@host )
|
29
|
+
@@conn.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 )
|
30
|
+
@@conn.bind
|
31
|
+
@@root_dse = @@conn.root_dse[0]
|
32
|
+
@@naming_context = @@root_dse['namingContexts'][0]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
undef_method :default_test
|
37
|
+
|
38
|
+
end
|
data/test/subschema.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
$test = File.dirname($0)
|
3
|
+
require "#{$test}/conf"
|
4
|
+
require "./ldap"
|
5
|
+
require "#{$test}/../lib/ldap/schema"
|
6
|
+
|
7
|
+
conn = LDAP::Conn.new($HOST, $PORT)
|
8
|
+
conn.bind{
|
9
|
+
schema = conn.schema()
|
10
|
+
p schema.must("person")
|
11
|
+
p schema.attr("person", "MUST")
|
12
|
+
p schema.may("person")
|
13
|
+
p schema.attr("person", "MAY")
|
14
|
+
p schema.sup("person")
|
15
|
+
p schema.attr("person", "SUP")
|
16
|
+
schema.each{|key,vals|
|
17
|
+
vals.each{|val|
|
18
|
+
print("#{key}: #{val}\n")
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
data/test/tc_conn.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# $Id: tc_conn.rb,v 1.3 2005/03/15 01:43:59 ianmacd Exp $
|
2
|
+
#
|
3
|
+
# A suite of unit tests for testing Ruby/LDAP connection functionality.
|
4
|
+
|
5
|
+
require 'ldap'
|
6
|
+
require 'test/unit'
|
7
|
+
require './setup'
|
8
|
+
|
9
|
+
class TC_ConnectionTest < TC_LDAPTest
|
10
|
+
|
11
|
+
# Ensure that rebinding works.
|
12
|
+
#
|
13
|
+
def test_rebind
|
14
|
+
id = @@conn.object_id
|
15
|
+
|
16
|
+
assert_nothing_raised do
|
17
|
+
@@conn.unbind
|
18
|
+
@@conn.bind
|
19
|
+
end
|
20
|
+
|
21
|
+
id2 = @@conn.object_id
|
22
|
+
assert_equal( id, id2 )
|
23
|
+
|
24
|
+
assert_nothing_raised do
|
25
|
+
@@conn.unbind
|
26
|
+
@@conn.simple_bind
|
27
|
+
end
|
28
|
+
|
29
|
+
id2 = @@conn.object_id
|
30
|
+
assert_equal( id, id2 )
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_double_bind
|
34
|
+
assert_raises( LDAP::Error ) { @@conn.bind }
|
35
|
+
assert_raises( LDAP::Error ) { @@conn.simple_bind }
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_double_unbind
|
39
|
+
assert_nothing_raised { @@conn.unbind }
|
40
|
+
assert_raises( LDAP::InvalidDataError ) { @@conn.unbind }
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_bound?
|
44
|
+
assert( @@conn.bound? )
|
45
|
+
@@conn.unbind
|
46
|
+
assert( ! @@conn.bound? )
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_sasl_bind
|
50
|
+
@@conn = LDAP::Conn.new( @@host )
|
51
|
+
@@conn.sasl_quiet = true
|
52
|
+
|
53
|
+
assert_nothing_raised { @@conn.sasl_bind( '', '' ) }
|
54
|
+
|
55
|
+
@@conn = nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_double_sasl_bind
|
59
|
+
@@conn = LDAP::Conn.new( @@host )
|
60
|
+
@@conn.sasl_quiet = true
|
61
|
+
|
62
|
+
assert_nothing_raised { @@conn.sasl_bind( '', '' ) }
|
63
|
+
assert_raises( LDAP::Error ) { @@conn.sasl_bind( '', '' ) }
|
64
|
+
|
65
|
+
@@conn = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_sasl_rebind
|
69
|
+
@@conn = LDAP::Conn.new( @@host )
|
70
|
+
@@conn.sasl_quiet = true
|
71
|
+
|
72
|
+
id = @@conn.object_id
|
73
|
+
|
74
|
+
assert_nothing_raised do
|
75
|
+
@@conn.unbind
|
76
|
+
@@conn.sasl_bind( '', '' )
|
77
|
+
end
|
78
|
+
|
79
|
+
id2 = @@conn.object_id
|
80
|
+
assert_equal( id, id2 )
|
81
|
+
|
82
|
+
@@conn = nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_ssl_rebind
|
86
|
+
@@conn = LDAP::SSLConn.new( @@host, LDAP::LDAPS_PORT )
|
87
|
+
|
88
|
+
id = @@conn.object_id
|
89
|
+
|
90
|
+
assert_nothing_raised do
|
91
|
+
@@conn.bind
|
92
|
+
@@conn.unbind
|
93
|
+
@@conn.bind
|
94
|
+
end
|
95
|
+
|
96
|
+
id2 = @@conn.object_id
|
97
|
+
assert_equal( id, id2 )
|
98
|
+
|
99
|
+
@@conn = nil
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_ssl_open
|
103
|
+
assert_raises( NotImplementedError ) { LDAP::SSLConn.open( @@host ) }
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_ssl_starttls_rebind
|
107
|
+
@@conn = LDAP::SSLConn.new( @@host, LDAP::LDAP_PORT, true )
|
108
|
+
|
109
|
+
id = @@conn.object_id
|
110
|
+
|
111
|
+
assert_nothing_raised do
|
112
|
+
@@conn.bind
|
113
|
+
@@conn.unbind
|
114
|
+
@@conn.bind
|
115
|
+
end
|
116
|
+
|
117
|
+
id2 = @@conn.object_id
|
118
|
+
assert_equal( id, id2 )
|
119
|
+
|
120
|
+
@@conn = nil
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
end
|
data/test/tc_ldif.rb
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
# $Id: tc_ldif.rb,v 1.5 2005/02/26 01:42:27 ianmacd Exp $
|
2
|
+
#
|
3
|
+
# A suite of unit tests for testing Ruby/LDAP LDIF functionality.
|
4
|
+
|
5
|
+
require 'ldap'
|
6
|
+
require 'ldap/ldif'
|
7
|
+
require 'ldap/control'
|
8
|
+
require 'test/unit'
|
9
|
+
|
10
|
+
class TC_LDIFTest < Test::Unit::TestCase
|
11
|
+
|
12
|
+
include LDAP::LDIF
|
13
|
+
|
14
|
+
def test_version_entry
|
15
|
+
ldif = File.open( 'data/ldif1.txt' ) { |f| f.readlines }
|
16
|
+
entry = nil
|
17
|
+
assert_nothing_raised { entry = LDAP::LDIF.parse_entry( ldif ) }
|
18
|
+
assert_instance_of( LDAP::Record, entry )
|
19
|
+
assert_instance_of( String, entry.dn )
|
20
|
+
assert_instance_of( Array, entry.attrs['objectclass'] )
|
21
|
+
assert( entry.attrs['objectclass'].length > 1 )
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_bad_version_entry
|
25
|
+
ldif = File.open( 'data/ldif2.txt' ) { |f| f.readlines }
|
26
|
+
assert_raise( LDIFError ) { LDAP::LDIF.parse_entry( ldif ) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_no_version_entry
|
30
|
+
ldif = File.open( 'data/ldif3.txt' ) { |f| f.readlines }
|
31
|
+
assert_nothing_raised { LDAP::LDIF.parse_entry( ldif ) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_file
|
35
|
+
entries = LDAP::LDIF.parse_file( 'data/ldif4.txt' )
|
36
|
+
assert_instance_of( Array, entries )
|
37
|
+
assert_instance_of( Hash, entries[0].attrs )
|
38
|
+
assert_not_equal( {}, entries[0].attrs )
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_folded_attribute_entry
|
42
|
+
ldif = File.open( 'data/ldif5.txt' ) { |f| f.readlines }
|
43
|
+
entry = nil
|
44
|
+
assert_nothing_raised { entry = LDAP::LDIF.parse_entry( ldif ) }
|
45
|
+
assert_no_match( /\n/, entry.attrs['description'][0] )
|
46
|
+
assert( entry.attrs['description'][0].length > LDAP::LDIF::LINE_LENGTH )
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_base64_value_entry
|
50
|
+
ldif = File.open( 'data/ldif6.txt' ) { |f| f.readlines }
|
51
|
+
entry = LDAP::LDIF.parse_entry( ldif )
|
52
|
+
assert_match( /\r/, entry.attrs['description'][0] )
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_utf8_file
|
56
|
+
entries = LDAP::LDIF.parse_file( 'data/ldif7.txt' )
|
57
|
+
assert_instance_of( Array, entries )
|
58
|
+
assert_instance_of( Hash, entries[0].attrs )
|
59
|
+
assert_not_equal( {}, entries[0].attrs )
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_external_file_entry
|
63
|
+
ldif = File.open( 'data/ldif8.txt' ) { |f| f.readlines }
|
64
|
+
entry = LDAP::LDIF.parse_entry( ldif )
|
65
|
+
assert( entry.attrs['jpegphoto'][0].size > 1024 )
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_change_records_file
|
69
|
+
entries = LDAP::LDIF.parse_file( 'data/ldif9.txt' )
|
70
|
+
assert_instance_of( Array, entries )
|
71
|
+
assert_instance_of( Hash, entries[0].attrs )
|
72
|
+
assert_not_equal( {}, entries[0].attrs )
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_bad_line_entry
|
76
|
+
ldif = File.open( 'data/ldif10.txt' ) { |f| f.readlines }
|
77
|
+
assert_raise( LDIFError ) { LDAP::LDIF.parse_entry( ldif ) }
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_bad_attr_entry
|
81
|
+
ldif = File.open( 'data/ldif11.txt' ) { |f| f.readlines }
|
82
|
+
assert_raise( LDIFError ) { LDAP::LDIF.parse_entry( ldif ) }
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_change_record_binary_replace_entry
|
86
|
+
ldif = File.open( 'data/ldif12.txt' ) { |f| f.readlines }
|
87
|
+
entry = LDAP::LDIF.parse_entry( ldif )
|
88
|
+
assert( entry.mods.keys.include?( LDAP::LDAP_MOD_REPLACE |
|
89
|
+
LDAP::LDAP_MOD_BVALUES ) )
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_change_record_control
|
93
|
+
ldif = File.open( 'data/ldif13.txt' ) { |f| f.readlines }
|
94
|
+
entry = LDAP::LDIF.parse_entry( ldif )
|
95
|
+
assert_instance_of( LDAP::Control, entry.controls[0] )
|
96
|
+
assert_equal( entry.controls[0].oid, '1.2.840.113556.1.4.805' )
|
97
|
+
assert( entry.controls[0].iscritical )
|
98
|
+
assert_nil( entry.controls[0].value )
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_change_record_control2
|
102
|
+
ldif = File.open( 'data/ldif14.txt' ) { |f| f.readlines }
|
103
|
+
entry = LDAP::LDIF.parse_entry( ldif )
|
104
|
+
assert_instance_of( LDAP::Control, entry.controls[0] )
|
105
|
+
assert_equal( entry.controls[0].oid, '1.2.3.4' )
|
106
|
+
assert_equal( entry.controls[0].iscritical, false )
|
107
|
+
assert_not_nil( entry.controls[0].value )
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_mod_to_ldif
|
111
|
+
mod = LDAP.mod( LDAP::LDAP_MOD_ADD | LDAP::LDAP_MOD_BVALUES,
|
112
|
+
'mailRoutingAddress', ['a', 'b'] )
|
113
|
+
assert_instance_of( LDAP::LDIF::Mod,
|
114
|
+
mod.to_ldif( 'uid=foo,dc=example,dc=com' ) )
|
115
|
+
assert_equal( <<LDIF, mod.to_ldif( 'uid=foo,dc=example,dc=com' ) )
|
116
|
+
dn: uid=foo,dc=example,dc=com
|
117
|
+
changetype: add
|
118
|
+
mailRoutingAddress: a
|
119
|
+
mailRoutingAddress: b
|
120
|
+
LDIF
|
121
|
+
|
122
|
+
mod = LDAP.mod( LDAP::LDAP_MOD_REPLACE | LDAP::LDAP_MOD_BVALUES,
|
123
|
+
'mailRoutingAddress', ['a', 'b'] )
|
124
|
+
assert_equal( <<LDIF, mod.to_ldif( 'uid=foo,dc=example,dc=com' ) )
|
125
|
+
dn: uid=foo,dc=example,dc=com
|
126
|
+
changetype: modify
|
127
|
+
replace: mailRoutingAddress
|
128
|
+
mailRoutingAddress: a
|
129
|
+
mailRoutingAddress: b
|
130
|
+
LDIF
|
131
|
+
|
132
|
+
mod = LDAP.mod( LDAP::LDAP_MOD_DELETE, 'mailRoutingAddress', ['a', 'b'] )
|
133
|
+
assert_equal( <<LDIF, mod.to_ldif( 'uid=foo,dc=example,dc=com' ) )
|
134
|
+
dn: uid=foo,dc=example,dc=com
|
135
|
+
changetype: delete
|
136
|
+
mailRoutingAddress: a
|
137
|
+
mailRoutingAddress: b
|
138
|
+
LDIF
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_mods_to_ldif
|
142
|
+
|
143
|
+
# Try passing an array of mods to LDAP::LDIF.mods_to_ldif.
|
144
|
+
|
145
|
+
# This must be a single line for the heredoc to work.
|
146
|
+
assert_equal( <<LDIF, LDAP::LDIF.mods_to_ldif( 'uid=ianmacd,dc=foo', [ LDAP.mod( LDAP::LDAP_MOD_ADD | LDAP::LDAP_MOD_BVALUES, 'mailRoutingAddress', ['a', 'b'] ), LDAP.mod( LDAP::LDAP_MOD_DELETE, 'location', [ 'amsterdam'] ), LDAP.mod( LDAP::LDAP_MOD_REPLACE, 'telephonenumber', [ '+1 408 555 1234', '+1 408 555 5678' ] ), LDAP.mod( LDAP::LDAP_MOD_DELETE, 'office', [] ) ] ) )
|
147
|
+
dn: uid=ianmacd,dc=foo
|
148
|
+
changetype: modify
|
149
|
+
add: mailRoutingAddress
|
150
|
+
mailRoutingAddress: a
|
151
|
+
mailRoutingAddress: b
|
152
|
+
-
|
153
|
+
delete: location
|
154
|
+
location: amsterdam
|
155
|
+
-
|
156
|
+
replace: telephonenumber
|
157
|
+
telephonenumber: +1 408 555 1234
|
158
|
+
telephonenumber: +1 408 555 5678
|
159
|
+
-
|
160
|
+
delete: office
|
161
|
+
LDIF
|
162
|
+
|
163
|
+
# Try passing a single mod to LDAP::LDIF.mods_to_ldif.
|
164
|
+
assert_equal( <<LDIF, LDAP::LDIF.mods_to_ldif( 'uid=ianmacd,dc=google,dc=com', LDAP.mod( LDAP::LDAP_MOD_REPLACE, 'telephonenumber', [ '+1 408 555 1234', '+1 408 555 5678' ] ) ) )
|
165
|
+
dn: uid=ianmacd,dc=google,dc=com
|
166
|
+
changetype: modify
|
167
|
+
replace: telephonenumber
|
168
|
+
telephonenumber: +1 408 555 1234
|
169
|
+
telephonenumber: +1 408 555 5678
|
170
|
+
LDIF
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
data/test/tc_schema.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# $Id: tc_schema.rb,v 1.4 2005/03/13 10:11:41 ianmacd Exp $
|
2
|
+
#
|
3
|
+
# A suite of unit tests for testing Ruby/LDAP schema functionality.
|
4
|
+
|
5
|
+
require 'ldap'
|
6
|
+
require 'ldap/schema'
|
7
|
+
require 'test/unit'
|
8
|
+
require './setup'
|
9
|
+
|
10
|
+
class TC_SchemaTest < TC_LDAPTest
|
11
|
+
|
12
|
+
def test_schema
|
13
|
+
schema = @@conn.schema
|
14
|
+
assert_instance_of( LDAP::Schema, schema )
|
15
|
+
assert( schema.key?( 'attributeTypes' ) )
|
16
|
+
assert( schema.key?( 'ldapSyntaxes' ) )
|
17
|
+
assert( schema.key?( 'matchingRules' ) )
|
18
|
+
assert( schema.key?( 'matchingRuleUse' ) )
|
19
|
+
assert( schema.key?( 'objectClasses' ) )
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_root_dse
|
23
|
+
root_dse = @@conn.root_dse[0]
|
24
|
+
assert( root_dse.key?( 'subschemaSubentry' ) )
|
25
|
+
assert( root_dse.key?( 'namingContexts' ) )
|
26
|
+
assert( root_dse.key?( 'supportedSASLMechanisms' ) )
|
27
|
+
assert( root_dse.key?( 'supportedControl' ) )
|
28
|
+
assert( root_dse.key?( 'supportedExtension' ) )
|
29
|
+
assert( root_dse.key?( 'supportedLDAPVersion' ) )
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/test/tc_search.rb
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
# $Id: tc_search.rb,v 1.4 2006/02/12 19:55:59 ianmacd Exp $
|
2
|
+
#
|
3
|
+
# A suite of unit tests for testing Ruby/LDAP search functionality.
|
4
|
+
|
5
|
+
require 'ldap'
|
6
|
+
require 'ldap/control'
|
7
|
+
require 'test/unit'
|
8
|
+
require './setup'
|
9
|
+
|
10
|
+
class TC_SearchTest < TC_LDAPTest
|
11
|
+
|
12
|
+
# Ensure that giving an incorrect attribute argument raises an exception
|
13
|
+
# and that passing a string instead of an array is treated as a single
|
14
|
+
# element array.
|
15
|
+
#
|
16
|
+
def test_attrs
|
17
|
+
assert_raise( TypeError ) do
|
18
|
+
@@conn.search( @@naming_context, LDAP::LDAP_SCOPE_ONELEVEL,
|
19
|
+
'(objectClass=*)', false )
|
20
|
+
end
|
21
|
+
|
22
|
+
@@conn.search( @@naming_context, LDAP::LDAP_SCOPE_ONELEVEL,
|
23
|
+
'(objectClass=*)', [], true ) do |x|
|
24
|
+
assert_nil( x['objectClass'] )
|
25
|
+
break
|
26
|
+
end
|
27
|
+
|
28
|
+
@@conn.search( @@naming_context, LDAP::LDAP_SCOPE_ONELEVEL,
|
29
|
+
'(objectClass=*)', 'objectClass' ) do |x|
|
30
|
+
x = x.to_hash
|
31
|
+
x.delete( 'dn' )
|
32
|
+
assert( x.to_hash.keys == [ 'objectClass' ] )
|
33
|
+
break
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Ensure that we can sort on a given attribute.
|
38
|
+
#
|
39
|
+
def test_sort_attr
|
40
|
+
ou = []
|
41
|
+
@@conn.search( @@naming_context, LDAP::LDAP_SCOPE_ONELEVEL,
|
42
|
+
'(ou=*)' ) do |x|
|
43
|
+
ou << x['ou']
|
44
|
+
end
|
45
|
+
ou.flatten!
|
46
|
+
|
47
|
+
sorted_ou = []
|
48
|
+
@@conn.search( @@naming_context, LDAP::LDAP_SCOPE_ONELEVEL,
|
49
|
+
'(ou=*)', nil, nil, 0, 0, 'ou' ) do |x|
|
50
|
+
sorted_ou << x['ou']
|
51
|
+
end
|
52
|
+
sorted_ou.flatten!
|
53
|
+
|
54
|
+
assert_not_equal( ou, sorted_ou )
|
55
|
+
assert_equal( ou.sort, sorted_ou )
|
56
|
+
end
|
57
|
+
|
58
|
+
# Ensure that we can pass a proc object to use for sorting.
|
59
|
+
#
|
60
|
+
def test_sort_proc
|
61
|
+
ct = []
|
62
|
+
@@conn.search( @@naming_context, LDAP::LDAP_SCOPE_ONELEVEL,
|
63
|
+
'(objectClass=*)', [ 'createTimestamp' ] ) do |x|
|
64
|
+
ct << x['createTimestamp']
|
65
|
+
end
|
66
|
+
ct.flatten!
|
67
|
+
|
68
|
+
sorted_ct = []
|
69
|
+
s_proc = proc { |a,b| b <=> a }
|
70
|
+
@@conn.search( @@naming_context, LDAP::LDAP_SCOPE_ONELEVEL,
|
71
|
+
'(objectClass=*)', [ 'createTimestamp' ], nil, 0, 0,
|
72
|
+
'createTimestamp', s_proc ) do |x|
|
73
|
+
sorted_ct << x['createTimestamp']
|
74
|
+
end
|
75
|
+
sorted_ct.flatten!
|
76
|
+
|
77
|
+
assert_not_equal( ct, sorted_ct )
|
78
|
+
assert_equal( ct.sort( &s_proc ), sorted_ct )
|
79
|
+
end
|
80
|
+
|
81
|
+
# Ensure that the paged results control works properly.
|
82
|
+
#
|
83
|
+
def test_paged_results
|
84
|
+
total = 0
|
85
|
+
page_size = 1
|
86
|
+
cookie = ''
|
87
|
+
|
88
|
+
loop do
|
89
|
+
ber_string = LDAP::Control.encode( page_size, cookie )
|
90
|
+
ctrl = LDAP::Control.new( LDAP::LDAP_CONTROL_PAGEDRESULTS,
|
91
|
+
ber_string,
|
92
|
+
true )
|
93
|
+
@@conn.set_option( LDAP::LDAP_OPT_SERVER_CONTROLS, [ ctrl ] )
|
94
|
+
|
95
|
+
this_page = nil
|
96
|
+
assert_nothing_raised do
|
97
|
+
begin
|
98
|
+
this_page = @@conn.search2( @@naming_context,
|
99
|
+
LDAP::LDAP_SCOPE_ONELEVEL,
|
100
|
+
'(objectclass=*)' )
|
101
|
+
rescue LDAP::ResultError
|
102
|
+
@@conn = nil
|
103
|
+
raise
|
104
|
+
end
|
105
|
+
end
|
106
|
+
total += this_page.size
|
107
|
+
assert_equal( page_size, this_page.size )
|
108
|
+
|
109
|
+
@@conn.controls.each do |c|
|
110
|
+
if c.oid == LDAP::LDAP_CONTROL_PAGEDRESULTS
|
111
|
+
ctrl = c
|
112
|
+
break
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
assert_equal( ctrl.oid, LDAP::LDAP_CONTROL_PAGEDRESULTS )
|
117
|
+
|
118
|
+
fetched_size, cookie = ctrl.decode
|
119
|
+
page_size = fetched_size if fetched_size.to_i > 0
|
120
|
+
|
121
|
+
break if cookie.empty?
|
122
|
+
end
|
123
|
+
|
124
|
+
# Reset connection.
|
125
|
+
@@conn = nil
|
126
|
+
setup
|
127
|
+
|
128
|
+
unpaged = @@conn.search2( @@naming_context, LDAP::LDAP_SCOPE_ONELEVEL,
|
129
|
+
'(objectclass=*)' )
|
130
|
+
|
131
|
+
# Does the total number of results match the equivalent unpaged search?
|
132
|
+
# This has a race condition, but we assume the number of top-level OUs is
|
133
|
+
# more or less static. :-)
|
134
|
+
assert_equal( total, unpaged.size )
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|