Feature #1060 » net-ldap-0.2.2_r5657.patch
vendor/plugins/ruby-net-ldap-0.0.4/tests/testldif.rb (working copy) | ||
---|---|---|
1 |
# $Id: testldif.rb 61 2006-04-18 20:55:55Z blackhedd $ |
|
2 |
# |
|
3 |
# |
|
4 | ||
5 | ||
6 |
$:.unshift "lib" |
|
7 | ||
8 |
require 'test/unit' |
|
9 | ||
10 |
require 'net/ldap' |
|
11 |
require 'net/ldif' |
|
12 | ||
13 |
require 'sha1' |
|
14 |
require 'base64' |
|
15 | ||
16 |
class TestLdif < Test::Unit::TestCase |
|
17 | ||
18 |
TestLdifFilename = "tests/testdata.ldif" |
|
19 | ||
20 |
def test_empty_ldif |
|
21 |
ds = Net::LDAP::Dataset::read_ldif( StringIO.new ) |
|
22 |
assert_equal( true, ds.empty? ) |
|
23 |
end |
|
24 | ||
25 |
def test_ldif_with_comments |
|
26 |
str = ["# Hello from LDIF-land", "# This is an unterminated comment"] |
|
27 |
io = StringIO.new( str[0] + "\r\n" + str[1] ) |
|
28 |
ds = Net::LDAP::Dataset::read_ldif( io ) |
|
29 |
assert_equal( str, ds.comments ) |
|
30 |
end |
|
31 | ||
32 |
def test_ldif_with_password |
|
33 |
psw = "goldbricks" |
|
34 |
hashed_psw = "{SHA}" + Base64::encode64( SHA1.new(psw).digest ).chomp |
|
35 | ||
36 |
ldif_encoded = Base64::encode64( hashed_psw ).chomp |
|
37 |
ds = Net::LDAP::Dataset::read_ldif( StringIO.new( "dn: Goldbrick\r\nuserPassword:: #{ldif_encoded}\r\n\r\n" )) |
|
38 |
recovered_psw = ds["Goldbrick"][:userpassword].shift |
|
39 |
assert_equal( hashed_psw, recovered_psw ) |
|
40 |
end |
|
41 | ||
42 |
def test_ldif_with_continuation_lines |
|
43 |
ds = Net::LDAP::Dataset::read_ldif( StringIO.new( "dn: abcdefg\r\n hijklmn\r\n\r\n" )) |
|
44 |
assert_equal( true, ds.has_key?( "abcdefg hijklmn" )) |
|
45 |
end |
|
46 | ||
47 |
# TODO, INADEQUATE. We need some more tests |
|
48 |
# to verify the content. |
|
49 |
def test_ldif |
|
50 |
File.open( TestLdifFilename, "r" ) {|f| |
|
51 |
ds = Net::LDAP::Dataset::read_ldif( f ) |
|
52 |
assert_equal( 13, ds.length ) |
|
53 |
} |
|
54 |
end |
|
55 | ||
56 |
# TODO, need some tests. |
|
57 |
# Must test folded lines and base64-encoded lines as well as normal ones. |
|
58 |
def test_to_ldif |
|
59 |
File.open( TestLdifFilename, "r" ) {|f| |
|
60 |
ds = Net::LDAP::Dataset::read_ldif( f ) |
|
61 |
ds.to_ldif |
|
62 |
assert_equal( true, false ) # REMOVE WHEN WE HAVE SOME TESTS HERE. |
|
63 |
} |
|
64 |
end |
|
65 | ||
66 | ||
67 |
end |
|
68 | ||
69 |
vendor/plugins/ruby-net-ldap-0.0.4/tests/testldap.rb (working copy) | ||
---|---|---|
1 |
# $Id: testldap.rb 65 2006-04-23 01:17:49Z blackhedd $ |
|
2 |
# |
|
3 |
# |
|
4 | ||
5 | ||
6 |
$:.unshift "lib" |
|
7 | ||
8 |
require 'test/unit' |
|
9 | ||
10 |
require 'net/ldap' |
|
11 |
require 'stringio' |
|
12 | ||
13 | ||
14 |
class TestLdapClient < Test::Unit::TestCase |
|
15 | ||
16 |
# TODO: these tests crash and burn if the associated |
|
17 |
# LDAP testserver isn't up and running. |
|
18 |
# We rely on being able to read a file with test data |
|
19 |
# in LDIF format. |
|
20 |
# TODO, WARNING: for the moment, this data is in a file |
|
21 |
# whose name and location are HARDCODED into the |
|
22 |
# instance method load_test_data. |
|
23 | ||
24 |
def setup |
|
25 |
@host = "127.0.0.1" |
|
26 |
@port = 3890 |
|
27 |
@auth = { |
|
28 |
:method => :simple, |
|
29 |
:username => "cn=bigshot,dc=bayshorenetworks,dc=com", |
|
30 |
:password => "opensesame" |
|
31 |
} |
|
32 | ||
33 |
@ldif = load_test_data |
|
34 |
end |
|
35 | ||
36 | ||
37 | ||
38 |
# Get some test data which will be used to validate |
|
39 |
# the responses from the test LDAP server we will |
|
40 |
# connect to. |
|
41 |
# TODO, Bogus: we are HARDCODING the location of the file for now. |
|
42 |
# |
|
43 |
def load_test_data |
|
44 |
ary = File.readlines( "tests/testdata.ldif" ) |
|
45 |
hash = {} |
|
46 |
while line = ary.shift and line.chomp! |
|
47 |
if line =~ /^dn:[\s]*/i |
|
48 |
dn = $' |
|
49 |
hash[dn] = {} |
|
50 |
while attr = ary.shift and attr.chomp! and attr =~ /^([\w]+)[\s]*:[\s]*/ |
|
51 |
hash[dn][$1.downcase.intern] ||= [] |
|
52 |
hash[dn][$1.downcase.intern] << $' |
|
53 |
end |
|
54 |
end |
|
55 |
end |
|
56 |
hash |
|
57 |
end |
|
58 | ||
59 | ||
60 | ||
61 |
# Binding tests. |
|
62 |
# Need tests for all kinds of network failures and incorrect auth. |
|
63 |
# TODO: Implement a class-level timeout for operations like bind. |
|
64 |
# Search has a timeout defined at the protocol level, other ops do not. |
|
65 |
# TODO, use constants for the LDAP result codes, rather than hardcoding them. |
|
66 |
def test_bind |
|
67 |
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth |
|
68 |
assert_equal( true, ldap.bind ) |
|
69 |
assert_equal( 0, ldap.get_operation_result.code ) |
|
70 |
assert_equal( "Success", ldap.get_operation_result.message ) |
|
71 | ||
72 |
bad_username = @auth.merge( {:username => "cn=badguy,dc=imposters,dc=com"} ) |
|
73 |
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => bad_username |
|
74 |
assert_equal( false, ldap.bind ) |
|
75 |
assert_equal( 48, ldap.get_operation_result.code ) |
|
76 |
assert_equal( "Inappropriate Authentication", ldap.get_operation_result.message ) |
|
77 | ||
78 |
bad_password = @auth.merge( {:password => "cornhusk"} ) |
|
79 |
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => bad_password |
|
80 |
assert_equal( false, ldap.bind ) |
|
81 |
assert_equal( 49, ldap.get_operation_result.code ) |
|
82 |
assert_equal( "Invalid Credentials", ldap.get_operation_result.message ) |
|
83 |
end |
|
84 | ||
85 | ||
86 | ||
87 |
def test_search |
|
88 |
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth |
|
89 | ||
90 |
search = {:base => "dc=smalldomain,dc=com"} |
|
91 |
assert_equal( false, ldap.search( search )) |
|
92 |
assert_equal( 32, ldap.get_operation_result.code ) |
|
93 |
|
|
94 |
search = {:base => "dc=bayshorenetworks,dc=com"} |
|
95 |
assert_equal( true, ldap.search( search )) |
|
96 |
assert_equal( 0, ldap.get_operation_result.code ) |
|
97 |
|
|
98 |
ldap.search( search ) {|res| |
|
99 |
assert_equal( res, @ldif ) |
|
100 |
} |
|
101 |
end |
|
102 |
|
|
103 | ||
104 | ||
105 | ||
106 |
# This is a helper routine for test_search_attributes. |
|
107 |
def internal_test_search_attributes attrs_to_search |
|
108 |
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth |
|
109 |
assert( ldap.bind ) |
|
110 | ||
111 |
search = { |
|
112 |
:base => "dc=bayshorenetworks,dc=com", |
|
113 |
:attributes => attrs_to_search |
|
114 |
} |
|
115 | ||
116 |
ldif = @ldif |
|
117 |
ldif.each {|dn,entry| |
|
118 |
entry.delete_if {|attr,value| |
|
119 |
! attrs_to_search.include?(attr) |
|
120 |
} |
|
121 |
} |
|
122 |
|
|
123 |
assert_equal( true, ldap.search( search )) |
|
124 |
ldap.search( search ) {|res| |
|
125 |
res_keys = res.keys.sort |
|
126 |
ldif_keys = ldif.keys.sort |
|
127 |
assert( res_keys, ldif_keys ) |
|
128 |
res.keys.each {|rk| |
|
129 |
assert( res[rk], ldif[rk] ) |
|
130 |
} |
|
131 |
} |
|
132 |
end |
|
133 | ||
134 | ||
135 |
def test_search_attributes |
|
136 |
internal_test_search_attributes [:mail] |
|
137 |
internal_test_search_attributes [:cn] |
|
138 |
internal_test_search_attributes [:ou] |
|
139 |
internal_test_search_attributes [:hasaccessprivilege] |
|
140 |
internal_test_search_attributes ["mail"] |
|
141 |
internal_test_search_attributes ["cn"] |
|
142 |
internal_test_search_attributes ["ou"] |
|
143 |
internal_test_search_attributes ["hasaccessrole"] |
|
144 | ||
145 |
internal_test_search_attributes [:mail, :cn, :ou, :hasaccessrole] |
|
146 |
internal_test_search_attributes [:mail, "cn", :ou, "hasaccessrole"] |
|
147 |
end |
|
148 | ||
149 | ||
150 |
def test_search_filters |
|
151 |
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth |
|
152 |
search = { |
|
153 |
:base => "dc=bayshorenetworks,dc=com", |
|
154 |
:filter => Net::LDAP::Filter.eq( "sn", "Fosse" ) |
|
155 |
} |
|
156 | ||
157 |
ldap.search( search ) {|res| |
|
158 |
p res |
|
159 |
} |
|
160 |
end |
|
161 | ||
162 | ||
163 | ||
164 |
def test_open |
|
165 |
ldap = Net::LDAP.new :host => @host, :port => @port, :auth => @auth |
|
166 |
ldap.open {|ldap| |
|
167 |
10.times { |
|
168 |
rc = ldap.search( :base => "dc=bayshorenetworks,dc=com" ) |
|
169 |
assert_equal( true, rc ) |
|
170 |
} |
|
171 |
} |
|
172 |
end |
|
173 | ||
174 | ||
175 |
def test_ldap_open |
|
176 |
Net::LDAP.open( :host => @host, :port => @port, :auth => @auth ) {|ldap| |
|
177 |
10.times { |
|
178 |
rc = ldap.search( :base => "dc=bayshorenetworks,dc=com" ) |
|
179 |
assert_equal( true, rc ) |
|
180 |
} |
|
181 |
} |
|
182 |
end |
|
183 | ||
184 | ||
185 | ||
186 | ||
187 | ||
188 |
end |
|
189 | ||
190 |
vendor/plugins/ruby-net-ldap-0.0.4/tests/testem.rb (working copy) | ||
---|---|---|
1 |
# $Id: testem.rb 121 2006-05-15 18:36:24Z blackhedd $ |
|
2 |
# |
|
3 |
# |
|
4 | ||
5 |
require 'test/unit' |
|
6 |
require 'tests/testber' |
|
7 |
require 'tests/testldif' |
|
8 |
require 'tests/testldap' |
|
9 |
require 'tests/testpsw' |
|
10 |
require 'tests/testfilter' |
|
11 | ||
12 |
vendor/plugins/ruby-net-ldap-0.0.4/tests/testdata.ldif (working copy) | ||
---|---|---|
1 |
# $Id: testdata.ldif 50 2006-04-17 17:57:33Z blackhedd $ |
|
2 |
# |
|
3 |
# This is test-data for an LDAP server in LDIF format. |
|
4 |
# |
|
5 |
dn: dc=bayshorenetworks,dc=com |
|
6 |
objectClass: dcObject |
|
7 |
objectClass: organization |
|
8 |
o: Bayshore Networks LLC |
|
9 |
dc: bayshorenetworks |
|
10 | ||
11 |
dn: cn=Manager,dc=bayshorenetworks,dc=com |
|
12 |
objectClass: organizationalrole |
|
13 |
cn: Manager |
|
14 | ||
15 |
dn: ou=people,dc=bayshorenetworks,dc=com |
|
16 |
objectClass: organizationalunit |
|
17 |
ou: people |
|
18 | ||
19 |
dn: ou=privileges,dc=bayshorenetworks,dc=com |
|
20 |
objectClass: organizationalunit |
|
21 |
ou: privileges |
|
22 | ||
23 |
dn: ou=roles,dc=bayshorenetworks,dc=com |
|
24 |
objectClass: organizationalunit |
|
25 |
ou: roles |
|
26 | ||
27 |
dn: ou=office,dc=bayshorenetworks,dc=com |
|
28 |
objectClass: organizationalunit |
|
29 |
ou: office |
|
30 | ||
31 |
dn: mail=nogoodnik@steamheat.net,ou=people,dc=bayshorenetworks,dc=com |
|
32 |
cn: Bob Fosse |
|
33 |
mail: nogoodnik@steamheat.net |
|
34 |
sn: Fosse |
|
35 |
ou: people |
|
36 |
objectClass: top |
|
37 |
objectClass: inetorgperson |
|
38 |
objectClass: authorizedperson |
|
39 |
hasAccessRole: uniqueIdentifier=engineer,ou=roles |
|
40 |
hasAccessRole: uniqueIdentifier=ldapadmin,ou=roles |
|
41 |
hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles |
|
42 |
hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles |
|
43 |
hasAccessRole: uniqueIdentifier=ogilvy_eagle_user,ou=roles |
|
44 |
hasAccessRole: uniqueIdentifier=greenplug_user,ou=roles |
|
45 |
hasAccessRole: uniqueIdentifier=brandplace_logging_user,ou=roles |
|
46 |
hasAccessRole: uniqueIdentifier=brandplace_report_user,ou=roles |
|
47 |
hasAccessRole: uniqueIdentifier=workorder_user,ou=roles |
|
48 |
hasAccessRole: uniqueIdentifier=bayshore_eagle_user,ou=roles |
|
49 |
hasAccessRole: uniqueIdentifier=bayshore_eagle_superuser,ou=roles |
|
50 |
hasAccessRole: uniqueIdentifier=kledaras_user,ou=roles |
|
51 | ||
52 |
dn: mail=elephant@steamheat.net,ou=people,dc=bayshorenetworks,dc=com |
|
53 |
cn: Gwen Verdon |
|
54 |
mail: elephant@steamheat.net |
|
55 |
sn: Verdon |
|
56 |
ou: people |
|
57 |
objectClass: top |
|
58 |
objectClass: inetorgperson |
|
59 |
objectClass: authorizedperson |
|
60 |
hasAccessRole: uniqueIdentifier=brandplace_report_user,ou=roles |
|
61 |
hasAccessRole: uniqueIdentifier=engineer,ou=roles |
|
62 |
hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles |
|
63 |
hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles |
|
64 |
hasAccessRole: uniqueIdentifier=ldapadmin,ou=roles |
|
65 | ||
66 |
dn: uniqueIdentifier=engineering,ou=privileges,dc=bayshorenetworks,dc=com |
|
67 |
uniqueIdentifier: engineering |
|
68 |
ou: privileges |
|
69 |
objectClass: accessPrivilege |
|
70 | ||
71 |
dn: uniqueIdentifier=engineer,ou=roles,dc=bayshorenetworks,dc=com |
|
72 |
uniqueIdentifier: engineer |
|
73 |
ou: roles |
|
74 |
objectClass: accessRole |
|
75 |
hasAccessPrivilege: uniqueIdentifier=engineering,ou=privileges |
|
76 | ||
77 |
dn: uniqueIdentifier=ldapadmin,ou=roles,dc=bayshorenetworks,dc=com |
|
78 |
uniqueIdentifier: ldapadmin |
|
79 |
ou: roles |
|
80 |
objectClass: accessRole |
|
81 | ||
82 |
dn: uniqueIdentifier=ldapsuperadmin,ou=roles,dc=bayshorenetworks,dc=com |
|
83 |
uniqueIdentifier: ldapsuperadmin |
|
84 |
ou: roles |
|
85 |
objectClass: accessRole |
|
86 | ||
87 |
dn: mail=catperson@steamheat.net,ou=people,dc=bayshorenetworks,dc=com |
|
88 |
cn: Sid Sorokin |
|
89 |
mail: catperson@steamheat.net |
|
90 |
sn: Sorokin |
|
91 |
ou: people |
|
92 |
objectClass: top |
|
93 |
objectClass: inetorgperson |
|
94 |
objectClass: authorizedperson |
|
95 |
hasAccessRole: uniqueIdentifier=engineer,ou=roles |
|
96 |
hasAccessRole: uniqueIdentifier=ogilvy_elephant_user,ou=roles |
|
97 |
hasAccessRole: uniqueIdentifier=ldapsuperadmin,ou=roles |
|
98 |
hasAccessRole: uniqueIdentifier=ogilvy_eagle_user,ou=roles |
|
99 |
hasAccessRole: uniqueIdentifier=greenplug_user,ou=roles |
|
100 |
hasAccessRole: uniqueIdentifier=workorder_user,ou=roles |
|
101 |
vendor/plugins/ruby-net-ldap-0.0.4/tests/testfilter.rb (working copy) | ||
---|---|---|
1 |
# $Id: testfilter.rb 122 2006-05-15 20:03:56Z blackhedd $ |
|
2 |
# |
|
3 |
# |
|
4 | ||
5 |
require 'test/unit' |
|
6 | ||
7 |
$:.unshift "lib" |
|
8 | ||
9 |
require 'net/ldap' |
|
10 | ||
11 | ||
12 |
class TestFilter < Test::Unit::TestCase |
|
13 | ||
14 |
def setup |
|
15 |
end |
|
16 | ||
17 | ||
18 |
def teardown |
|
19 |
end |
|
20 | ||
21 |
def test_rfc_2254 |
|
22 |
p Net::LDAP::Filter.from_rfc2254( " ( uid=george* ) " ) |
|
23 |
p Net::LDAP::Filter.from_rfc2254( "uid!=george*" ) |
|
24 |
p Net::LDAP::Filter.from_rfc2254( "uid<george*" ) |
|
25 |
p Net::LDAP::Filter.from_rfc2254( "uid <= george*" ) |
|
26 |
p Net::LDAP::Filter.from_rfc2254( "uid>george*" ) |
|
27 |
p Net::LDAP::Filter.from_rfc2254( "uid>=george*" ) |
|
28 |
p Net::LDAP::Filter.from_rfc2254( "uid!=george*" ) |
|
29 | ||
30 |
p Net::LDAP::Filter.from_rfc2254( "(& (uid!=george* ) (mail=*))" ) |
|
31 |
p Net::LDAP::Filter.from_rfc2254( "(| (uid!=george* ) (mail=*))" ) |
|
32 |
p Net::LDAP::Filter.from_rfc2254( "(! (mail=*))" ) |
|
33 |
end |
|
34 | ||
35 | ||
36 |
end |
|
37 |
vendor/plugins/ruby-net-ldap-0.0.4/tests/testber.rb (working copy) | ||
---|---|---|
1 |
# $Id: testber.rb 57 2006-04-18 00:18:48Z blackhedd $ |
|
2 |
# |
|
3 |
# |
|
4 | ||
5 | ||
6 |
$:.unshift "lib" |
|
7 | ||
8 |
require 'net/ldap' |
|
9 |
require 'stringio' |
|
10 | ||
11 | ||
12 |
class TestBer < Test::Unit::TestCase |
|
13 | ||
14 |
def setup |
|
15 |
end |
|
16 | ||
17 |
# TODO: Add some much bigger numbers |
|
18 |
# 5000000000 is a Bignum, which hits different code. |
|
19 |
def test_ber_integers |
|
20 |
assert_equal( "\002\001\005", 5.to_ber ) |
|
21 |
assert_equal( "\002\002\203t", 500.to_ber ) |
|
22 |
assert_equal( "\002\003\203\206P", 50000.to_ber ) |
|
23 |
assert_equal( "\002\005\222\320\227\344\000", 5000000000.to_ber ) |
|
24 |
end |
|
25 | ||
26 |
def test_ber_parsing |
|
27 |
assert_equal( 6, "\002\001\006".read_ber( Net::LDAP::AsnSyntax )) |
|
28 |
assert_equal( "testing", "\004\007testing".read_ber( Net::LDAP::AsnSyntax )) |
|
29 |
end |
|
30 | ||
31 | ||
32 |
def test_ber_parser_on_ldap_bind_request |
|
33 |
s = StringIO.new "0$\002\001\001`\037\002\001\003\004\rAdministrator\200\vad_is_bogus" |
|
34 |
assert_equal( [1, [3, "Administrator", "ad_is_bogus"]], s.read_ber( Net::LDAP::AsnSyntax )) |
|
35 |
end |
|
36 | ||
37 | ||
38 | ||
39 | ||
40 |
end |
|
41 | ||
42 |
vendor/plugins/ruby-net-ldap-0.0.4/tests/testpsw.rb (working copy) | ||
---|---|---|
1 |
# $Id: testpsw.rb 72 2006-04-24 21:58:14Z blackhedd $ |
|
2 |
# |
|
3 |
# |
|
4 | ||
5 | ||
6 |
$:.unshift "lib" |
|
7 | ||
8 |
require 'net/ldap' |
|
9 |
require 'stringio' |
|
10 | ||
11 | ||
12 |
class TestPassword < Test::Unit::TestCase |
|
13 | ||
14 |
def setup |
|
15 |
end |
|
16 | ||
17 | ||
18 |
def test_psw |
|
19 |
assert_equal( "{MD5}xq8jwrcfibi0sZdZYNkSng==", Net::LDAP::Password.generate( :md5, "cashflow" )) |
|
20 |
assert_equal( "{SHA}YE4eGkN4BvwNN1f5R7CZz0kFn14=", Net::LDAP::Password.generate( :sha, "cashflow" )) |
|
21 |
end |
|
22 | ||
23 | ||
24 | ||
25 | ||
26 |
end |
|
27 | ||
28 |
vendor/plugins/ruby-net-ldap-0.0.4/LICENCE (working copy) | ||
---|---|---|
1 |
Net::LDAP is copyrighted free software by Francis Cianfrocca |
|
2 |
<garbagecat10@gmail.com>. You can redistribute it and/or modify it under either |
|
3 |
the terms of the GPL (see the file COPYING), or the conditions below: |
|
4 | ||
5 |
1. You may make and give away verbatim copies of the source form of the |
|
6 |
software without restriction, provided that you duplicate all of the |
|
7 |
original copyright notices and associated disclaimers. |
|
8 | ||
9 |
2. You may modify your copy of the software in any way, provided that you do |
|
10 |
at least ONE of the following: |
|
11 | ||
12 |
a) place your modifications in the Public Domain or otherwise make them |
|
13 |
Freely Available, such as by posting said modifications to Usenet or |
|
14 |
an equivalent medium, or by allowing the author to include your |
|
15 |
modifications in the software. |
|
16 | ||
17 |
b) use the modified software only within your corporation or |
|
18 |
organization. |
|
19 | ||
20 |
c) rename any non-standard executables so the names do not conflict with |
|
21 |
standard executables, which must also be provided. |
|
22 | ||
23 |
d) make other distribution arrangements with the author. |
|
24 | ||
25 |
3. You may distribute the software in object code or executable form, |
|
26 |
provided that you do at least ONE of the following: |
|
27 | ||
28 |
a) distribute the executables and library files of the software, together |
|
29 |
with instructions (in the manual page or equivalent) on where to get |
|
30 |
the original distribution. |
|
31 | ||
32 |
b) accompany the distribution with the machine-readable source of the |
|
33 |
software. |
|
34 | ||
35 |
c) give non-standard executables non-standard names, with instructions on |
|
36 |
where to get the original software distribution. |
|
37 | ||
38 |
d) make other distribution arrangements with the author. |
|
39 | ||
40 |
4. You may modify and include the part of the software into any other |
|
41 |
software (possibly commercial). But some files in the distribution are |
|
42 |
not written by the author, so that they are not under this terms. |
|
43 | ||
44 |
They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some |
|
45 |
files under the ./missing directory. See each file for the copying |
|
46 |
condition. |
|
47 | ||
48 |
5. The scripts and library files supplied as input to or produced as output |
|
49 |
from the software do not automatically fall under the copyright of the |
|
50 |
software, but belong to whomever generated them, and may be sold |
|
51 |
commercially, and may be aggregated with this software. |
|
52 | ||
53 |
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED |
|
54 |
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
|
55 |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/entry.rb (working copy) | ||
---|---|---|
1 |
# $Id: entry.rb 123 2006-05-18 03:52:38Z blackhedd $ |
|
2 |
# |
|
3 |
# LDAP Entry (search-result) support classes |
|
4 |
# |
|
5 |
# |
|
6 |
#---------------------------------------------------------------------------- |
|
7 |
# |
|
8 |
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. |
|
9 |
# |
|
10 |
# Gmail: garbagecat10 |
|
11 |
# |
|
12 |
# This program is free software; you can redistribute it and/or modify |
|
13 |
# it under the terms of the GNU General Public License as published by |
|
14 |
# the Free Software Foundation; either version 2 of the License, or |
|
15 |
# (at your option) any later version. |
|
16 |
# |
|
17 |
# This program is distributed in the hope that it will be useful, |
|
18 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 |
# GNU General Public License for more details. |
|
21 |
# |
|
22 |
# You should have received a copy of the GNU General Public License |
|
23 |
# along with this program; if not, write to the Free Software |
|
24 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
25 |
# |
|
26 |
#--------------------------------------------------------------------------- |
|
27 |
# |
|
28 | ||
29 | ||
30 | ||
31 | ||
32 |
module Net |
|
33 |
class LDAP |
|
34 | ||
35 | ||
36 |
# Objects of this class represent individual entries in an LDAP |
|
37 |
# directory. User code generally does not instantiate this class. |
|
38 |
# Net::LDAP#search provides objects of this class to user code, |
|
39 |
# either as block parameters or as return values. |
|
40 |
# |
|
41 |
# In LDAP-land, an "entry" is a collection of attributes that are |
|
42 |
# uniquely and globally identified by a DN ("Distinguished Name"). |
|
43 |
# Attributes are identified by short, descriptive words or phrases. |
|
44 |
# Although a directory is |
|
45 |
# free to implement any attribute name, most of them follow rigorous |
|
46 |
# standards so that the range of commonly-encountered attribute |
|
47 |
# names is not large. |
|
48 |
# |
|
49 |
# An attribute name is case-insensitive. Most directories also |
|
50 |
# restrict the range of characters allowed in attribute names. |
|
51 |
# To simplify handling attribute names, Net::LDAP::Entry |
|
52 |
# internally converts them to a standard format. Therefore, the |
|
53 |
# methods which take attribute names can take Strings or Symbols, |
|
54 |
# and work correctly regardless of case or capitalization. |
|
55 |
# |
|
56 |
# An attribute consists of zero or more data items called |
|
57 |
# <i>values.</i> An entry is the combination of a unique DN, a set of attribute |
|
58 |
# names, and a (possibly-empty) array of values for each attribute. |
|
59 |
# |
|
60 |
# Class Net::LDAP::Entry provides convenience methods for dealing |
|
61 |
# with LDAP entries. |
|
62 |
# In addition to the methods documented below, you may access individual |
|
63 |
# attributes of an entry simply by giving the attribute name as |
|
64 |
# the name of a method call. For example: |
|
65 |
# ldap.search( ... ) do |entry| |
|
66 |
# puts "Common name: #{entry.cn}" |
|
67 |
# puts "Email addresses:" |
|
68 |
# entry.mail.each {|ma| puts ma} |
|
69 |
# end |
|
70 |
# If you use this technique to access an attribute that is not present |
|
71 |
# in a particular Entry object, a NoMethodError exception will be raised. |
|
72 |
# |
|
73 |
#-- |
|
74 |
# Ugly problem to fix someday: We key off the internal hash with |
|
75 |
# a canonical form of the attribute name: convert to a string, |
|
76 |
# downcase, then take the symbol. Unfortunately we do this in |
|
77 |
# at least three places. Should do it in ONE place. |
|
78 |
class Entry |
|
79 | ||
80 |
# This constructor is not generally called by user code. |
|
81 |
def initialize dn = nil # :nodoc: |
|
82 |
@myhash = Hash.new {|k,v| k[v] = [] } |
|
83 |
@myhash[:dn] = [dn] |
|
84 |
end |
|
85 | ||
86 | ||
87 |
def []= name, value # :nodoc: |
|
88 |
sym = name.to_s.downcase.intern |
|
89 |
@myhash[sym] = value |
|
90 |
end |
|
91 | ||
92 | ||
93 |
#-- |
|
94 |
# We have to deal with this one as we do with []= |
|
95 |
# because this one and not the other one gets called |
|
96 |
# in formulations like entry["CN"] << cn. |
|
97 |
# |
|
98 |
def [] name # :nodoc: |
|
99 |
name = name.to_s.downcase.intern unless name.is_a?(Symbol) |
|
100 |
@myhash[name] |
|
101 |
end |
|
102 | ||
103 |
# Returns the dn of the Entry as a String. |
|
104 |
def dn |
|
105 |
self[:dn][0] |
|
106 |
end |
|
107 | ||
108 |
# Returns an array of the attribute names present in the Entry. |
|
109 |
def attribute_names |
|
110 |
@myhash.keys |
|
111 |
end |
|
112 | ||
113 |
# Accesses each of the attributes present in the Entry. |
|
114 |
# Calls a user-supplied block with each attribute in turn, |
|
115 |
# passing two arguments to the block: a Symbol giving |
|
116 |
# the name of the attribute, and a (possibly empty) |
|
117 |
# Array of data values. |
|
118 |
# |
|
119 |
def each |
|
120 |
if block_given? |
|
121 |
attribute_names.each {|a| |
|
122 |
attr_name,values = a,self[a] |
|
123 |
yield attr_name, values |
|
124 |
} |
|
125 |
end |
|
126 |
end |
|
127 | ||
128 |
alias_method :each_attribute, :each |
|
129 | ||
130 | ||
131 |
#-- |
|
132 |
# Convenience method to convert unknown method names |
|
133 |
# to attribute references. Of course the method name |
|
134 |
# comes to us as a symbol, so let's save a little time |
|
135 |
# and not bother with the to_s.downcase two-step. |
|
136 |
# Of course that means that a method name like mAIL |
|
137 |
# won't work, but we shouldn't be encouraging that |
|
138 |
# kind of bad behavior in the first place. |
|
139 |
# Maybe we should thow something if the caller sends |
|
140 |
# arguments or a block... |
|
141 |
# |
|
142 |
def method_missing *args, &block # :nodoc: |
|
143 |
s = args[0].to_s.downcase.intern |
|
144 |
if attribute_names.include?(s) |
|
145 |
self[s] |
|
146 |
elsif s.to_s[-1] == 61 and s.to_s.length > 1 |
|
147 |
value = args[1] or raise RuntimeError.new( "unable to set value" ) |
|
148 |
value = [value] unless value.is_a?(Array) |
|
149 |
name = s.to_s[0..-2].intern |
|
150 |
self[name] = value |
|
151 |
else |
|
152 |
raise NoMethodError.new( "undefined method '#{s}'" ) |
|
153 |
end |
|
154 |
end |
|
155 | ||
156 |
def write |
|
157 |
end |
|
158 | ||
159 |
end # class Entry |
|
160 | ||
161 | ||
162 |
end # class LDAP |
|
163 |
end # module Net |
|
164 | ||
165 |
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/dataset.rb (working copy) | ||
---|---|---|
1 |
# $Id: dataset.rb 78 2006-04-26 02:57:34Z blackhedd $ |
|
2 |
# |
|
3 |
# |
|
4 |
#---------------------------------------------------------------------------- |
|
5 |
# |
|
6 |
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. |
|
7 |
# |
|
8 |
# Gmail: garbagecat10 |
|
9 |
# |
|
10 |
# This program is free software; you can redistribute it and/or modify |
|
11 |
# it under the terms of the GNU General Public License as published by |
|
12 |
# the Free Software Foundation; either version 2 of the License, or |
|
13 |
# (at your option) any later version. |
|
14 |
# |
|
15 |
# This program is distributed in the hope that it will be useful, |
|
16 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
# GNU General Public License for more details. |
|
19 |
# |
|
20 |
# You should have received a copy of the GNU General Public License |
|
21 |
# along with this program; if not, write to the Free Software |
|
22 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
23 |
# |
|
24 |
#--------------------------------------------------------------------------- |
|
25 |
# |
|
26 |
# |
|
27 | ||
28 | ||
29 | ||
30 | ||
31 |
module Net |
|
32 |
class LDAP |
|
33 | ||
34 |
class Dataset < Hash |
|
35 | ||
36 |
attr_reader :comments |
|
37 | ||
38 | ||
39 |
def Dataset::read_ldif io |
|
40 |
ds = Dataset.new |
|
41 | ||
42 |
line = io.gets && chomp |
|
43 |
dn = nil |
|
44 | ||
45 |
while line |
|
46 |
io.gets and chomp |
|
47 |
if $_ =~ /^[\s]+/ |
|
48 |
line << " " << $' |
|
49 |
else |
|
50 |
nextline = $_ |
|
51 | ||
52 |
if line =~ /^\#/ |
|
53 |
ds.comments << line |
|
54 |
elsif line =~ /^dn:[\s]*/i |
|
55 |
dn = $' |
|
56 |
ds[dn] = Hash.new {|k,v| k[v] = []} |
|
57 |
elsif line.length == 0 |
|
58 |
dn = nil |
|
59 |
elsif line =~ /^([^:]+):([\:]?)[\s]*/ |
|
60 |
# $1 is the attribute name |
|
61 |
# $2 is a colon iff the attr-value is base-64 encoded |
|
62 |
# $' is the attr-value |
|
63 |
# Avoid the Base64 class because not all Ruby versions have it. |
|
64 |
attrvalue = ($2 == ":") ? $'.unpack('m').shift : $' |
|
65 |
ds[dn][$1.downcase.intern] << attrvalue |
|
66 |
end |
|
67 | ||
68 |
line = nextline |
|
69 |
end |
|
70 |
end |
|
71 |
|
|
72 |
ds |
|
73 |
end |
|
74 | ||
75 | ||
76 |
def initialize |
|
77 |
@comments = [] |
|
78 |
end |
|
79 | ||
80 | ||
81 |
def to_ldif |
|
82 |
ary = [] |
|
83 |
ary += (@comments || []) |
|
84 | ||
85 |
keys.sort.each {|dn| |
|
86 |
ary << "dn: #{dn}" |
|
87 | ||
88 |
self[dn].keys.map {|sym| sym.to_s}.sort.each {|attr| |
|
89 |
self[dn][attr.intern].each {|val| |
|
90 |
ary << "#{attr}: #{val}" |
|
91 |
} |
|
92 |
} |
|
93 | ||
94 |
ary << "" |
|
95 |
} |
|
96 | ||
97 |
block_given? and ary.each {|line| yield line} |
|
98 | ||
99 |
ary |
|
100 |
end |
|
101 | ||
102 | ||
103 |
end # Dataset |
|
104 | ||
105 |
end # LDAP |
|
106 |
end # Net |
|
107 | ||
108 |
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/filter.rb (working copy) | ||
---|---|---|
1 |
# $Id: filter.rb 151 2006-08-15 08:34:53Z blackhedd $ |
|
2 |
# |
|
3 |
# |
|
4 |
#---------------------------------------------------------------------------- |
|
5 |
# |
|
6 |
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. |
|
7 |
# |
|
8 |
# Gmail: garbagecat10 |
|
9 |
# |
|
10 |
# This program is free software; you can redistribute it and/or modify |
|
11 |
# it under the terms of the GNU General Public License as published by |
|
12 |
# the Free Software Foundation; either version 2 of the License, or |
|
13 |
# (at your option) any later version. |
|
14 |
# |
|
15 |
# This program is distributed in the hope that it will be useful, |
|
16 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
# GNU General Public License for more details. |
|
19 |
# |
|
20 |
# You should have received a copy of the GNU General Public License |
|
21 |
# along with this program; if not, write to the Free Software |
|
22 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
23 |
# |
|
24 |
#--------------------------------------------------------------------------- |
|
25 |
# |
|
26 |
# |
|
27 | ||
28 | ||
29 |
module Net |
|
30 |
class LDAP |
|
31 | ||
32 | ||
33 |
# Class Net::LDAP::Filter is used to constrain |
|
34 |
# LDAP searches. An object of this class is |
|
35 |
# passed to Net::LDAP#search in the parameter :filter. |
|
36 |
# |
|
37 |
# Net::LDAP::Filter supports the complete set of search filters |
|
38 |
# available in LDAP, including conjunction, disjunction and negation |
|
39 |
# (AND, OR, and NOT). This class supplants the (infamous) RFC-2254 |
|
40 |
# standard notation for specifying LDAP search filters. |
|
41 |
# |
|
42 |
# Here's how to code the familiar "objectclass is present" filter: |
|
43 |
# f = Net::LDAP::Filter.pres( "objectclass" ) |
|
44 |
# The object returned by this code can be passed directly to |
|
45 |
# the <tt>:filter</tt> parameter of Net::LDAP#search. |
|
46 |
# |
|
47 |
# See the individual class and instance methods below for more examples. |
|
48 |
# |
|
49 |
class Filter |
|
50 | ||
51 |
def initialize op, a, b |
|
52 |
@op = op |
|
53 |
@left = a |
|
54 |
@right = b |
|
55 |
end |
|
56 | ||
57 |
# #eq creates a filter object indicating that the value of |
|
58 |
# a paticular attribute must be either <i>present</i> or must |
|
59 |
# match a particular string. |
|
60 |
# |
|
61 |
# To specify that an attribute is "present" means that only |
|
62 |
# directory entries which contain a value for the particular |
|
63 |
# attribute will be selected by the filter. This is useful |
|
64 |
# in case of optional attributes such as <tt>mail.</tt> |
|
65 |
# Presence is indicated by giving the value "*" in the second |
|
66 |
# parameter to #eq. This example selects only entries that have |
|
67 |
# one or more values for <tt>sAMAccountName:</tt> |
|
68 |
# f = Net::LDAP::Filter.eq( "sAMAccountName", "*" ) |
|
69 |
# |
|
70 |
# To match a particular range of values, pass a string as the |
|
71 |
# second parameter to #eq. The string may contain one or more |
|
72 |
# "*" characters as wildcards: these match zero or more occurrences |
|
73 |
# of any character. Full regular-expressions are <i>not</i> supported |
|
74 |
# due to limitations in the underlying LDAP protocol. |
|
75 |
# This example selects any entry with a <tt>mail</tt> value containing |
|
76 |
# the substring "anderson": |
|
77 |
# f = Net::LDAP::Filter.eq( "mail", "*anderson*" ) |
|
78 |
#-- |
|
79 |
# Removed gt and lt. They ain't in the standard! |
|
80 |
# |
|
81 |
def Filter::eq attribute, value; Filter.new :eq, attribute, value; end |
|
82 |
def Filter::ne attribute, value; Filter.new :ne, attribute, value; end |
|
83 |
#def Filter::gt attribute, value; Filter.new :gt, attribute, value; end |
|
84 |
#def Filter::lt attribute, value; Filter.new :lt, attribute, value; end |
|
85 |
def Filter::ge attribute, value; Filter.new :ge, attribute, value; end |
|
86 |
def Filter::le attribute, value; Filter.new :le, attribute, value; end |
|
87 | ||
88 |
# #pres( attribute ) is a synonym for #eq( attribute, "*" ) |
|
89 |
# |
|
90 |
def Filter::pres attribute; Filter.eq attribute, "*"; end |
|
91 | ||
92 |
# operator & ("AND") is used to conjoin two or more filters. |
|
93 |
# This expression will select only entries that have an <tt>objectclass</tt> |
|
94 |
# attribute AND have a <tt>mail</tt> attribute that begins with "George": |
|
95 |
# f = Net::LDAP::Filter.pres( "objectclass" ) & Net::LDAP::Filter.eq( "mail", "George*" ) |
|
96 |
# |
|
97 |
def & filter; Filter.new :and, self, filter; end |
|
98 | ||
99 |
# operator | ("OR") is used to disjoin two or more filters. |
|
100 |
# This expression will select entries that have either an <tt>objectclass</tt> |
|
101 |
# attribute OR a <tt>mail</tt> attribute that begins with "George": |
|
102 |
# f = Net::LDAP::Filter.pres( "objectclass" ) | Net::LDAP::Filter.eq( "mail", "George*" ) |
|
103 |
# |
|
104 |
def | filter; Filter.new :or, self, filter; end |
|
105 | ||
106 | ||
107 |
# |
|
108 |
# operator ~ ("NOT") is used to negate a filter. |
|
109 |
# This expression will select only entries that <i>do not</i> have an <tt>objectclass</tt> |
|
110 |
# attribute: |
|
111 |
# f = ~ Net::LDAP::Filter.pres( "objectclass" ) |
|
112 |
# |
|
113 |
#-- |
|
114 |
# This operator can't be !, evidently. Try it. |
|
115 |
# Removed GT and LT. They're not in the RFC. |
|
116 |
def ~@; Filter.new :not, self, nil; end |
|
117 | ||
118 | ||
119 |
def to_s |
|
120 |
case @op |
|
121 |
when :ne |
|
122 |
"(!(#{@left}=#{@right}))" |
|
123 |
when :eq |
|
124 |
"(#{@left}=#{@right})" |
|
125 |
#when :gt |
|
126 |
# "#{@left}>#{@right}" |
|
127 |
#when :lt |
|
128 |
# "#{@left}<#{@right}" |
|
129 |
when :ge |
|
130 |
"#{@left}>=#{@right}" |
|
131 |
when :le |
|
132 |
"#{@left}<=#{@right}" |
|
133 |
when :and |
|
134 |
"(&(#{@left})(#{@right}))" |
|
135 |
when :or |
|
136 |
"(|(#{@left})(#{@right}))" |
|
137 |
when :not |
|
138 |
"(!(#{@left}))" |
|
139 |
else |
|
140 |
raise "invalid or unsupported operator in LDAP Filter" |
|
141 |
end |
|
142 |
end |
|
143 | ||
144 | ||
145 |
#-- |
|
146 |
# to_ber |
|
147 |
# Filter ::= |
|
148 |
# CHOICE { |
|
149 |
# and [0] SET OF Filter, |
|
150 |
# or [1] SET OF Filter, |
|
151 |
# not [2] Filter, |
|
152 |
# equalityMatch [3] AttributeValueAssertion, |
|
153 |
# substrings [4] SubstringFilter, |
|
154 |
# greaterOrEqual [5] AttributeValueAssertion, |
|
155 |
# lessOrEqual [6] AttributeValueAssertion, |
|
156 |
# present [7] AttributeType, |
|
157 |
# approxMatch [8] AttributeValueAssertion |
|
158 |
# } |
|
159 |
# |
|
160 |
# SubstringFilter |
|
161 |
# SEQUENCE { |
|
162 |
# type AttributeType, |
|
163 |
# SEQUENCE OF CHOICE { |
|
164 |
# initial [0] LDAPString, |
|
165 |
# any [1] LDAPString, |
|
166 |
# final [2] LDAPString |
|
167 |
# } |
|
168 |
# } |
|
169 |
# |
|
170 |
# Parsing substrings is a little tricky. |
|
171 |
# We use the split method to break a string into substrings |
|
172 |
# delimited by the * (star) character. But we also need |
|
173 |
# to know whether there is a star at the head and tail |
|
174 |
# of the string. A Ruby particularity comes into play here: |
|
175 |
# if you split on * and the first character of the string is |
|
176 |
# a star, then split will return an array whose first element |
|
177 |
# is an _empty_ string. But if the _last_ character of the |
|
178 |
# string is star, then split will return an array that does |
|
179 |
# _not_ add an empty string at the end. So we have to deal |
|
180 |
# with all that specifically. |
|
181 |
# |
|
182 |
def to_ber |
|
183 |
case @op |
|
184 |
when :eq |
|
185 |
if @right == "*" # present |
|
186 |
@left.to_s.to_ber_contextspecific 7 |
|
187 |
elsif @right =~ /[\*]/ #substring |
|
188 |
ary = @right.split( /[\*]+/ ) |
|
189 |
final_star = @right =~ /[\*]$/ |
|
190 |
initial_star = ary.first == "" and ary.shift |
|
191 | ||
192 |
seq = [] |
|
193 |
unless initial_star |
|
194 |
seq << ary.shift.to_ber_contextspecific(0) |
|
195 |
end |
|
196 |
n_any_strings = ary.length - (final_star ? 0 : 1) |
|
197 |
#p n_any_strings |
|
198 |
n_any_strings.times { |
|
199 |
seq << ary.shift.to_ber_contextspecific(1) |
|
200 |
} |
|
201 |
unless final_star |
|
202 |
seq << ary.shift.to_ber_contextspecific(2) |
|
203 |
end |
|
204 |
[@left.to_s.to_ber, seq.to_ber].to_ber_contextspecific 4 |
|
205 |
else #equality |
|
206 |
[@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 3 |
|
207 |
end |
|
208 |
when :ge |
|
209 |
[@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 5 |
|
210 |
when :le |
|
211 |
[@left.to_s.to_ber, @right.to_ber].to_ber_contextspecific 6 |
|
212 |
when :and |
|
213 |
ary = [@left.coalesce(:and), @right.coalesce(:and)].flatten |
|
214 |
ary.map {|a| a.to_ber}.to_ber_contextspecific( 0 ) |
|
215 |
when :or |
|
216 |
ary = [@left.coalesce(:or), @right.coalesce(:or)].flatten |
|
217 |
ary.map {|a| a.to_ber}.to_ber_contextspecific( 1 ) |
|
218 |
when :not |
|
219 |
[@left.to_ber].to_ber_contextspecific 2 |
|
220 |
else |
|
221 |
# ERROR, we'll return objectclass=* to keep things from blowing up, |
|
222 |
# but that ain't a good answer and we need to kick out an error of some kind. |
|
223 |
raise "unimplemented search filter" |
|
224 |
end |
|
225 |
end |
|
226 | ||
227 |
#-- |
|
228 |
# coalesce |
|
229 |
# This is a private helper method for dealing with chains of ANDs and ORs |
|
230 |
# that are longer than two. If BOTH of our branches are of the specified |
|
231 |
# type of joining operator, then return both of them as an array (calling |
|
232 |
# coalesce recursively). If they're not, then return an array consisting |
|
233 |
# only of self. |
|
234 |
# |
|
235 |
def coalesce operator |
|
236 |
if @op == operator |
|
237 |
[@left.coalesce( operator ), @right.coalesce( operator )] |
|
238 |
else |
|
239 |
[self] |
|
240 |
end |
|
241 |
end |
|
242 | ||
243 | ||
244 | ||
245 |
#-- |
|
246 |
# We get a Ruby object which comes from parsing an RFC-1777 "Filter" |
|
247 |
# object. Convert it to a Net::LDAP::Filter. |
|
248 |
# TODO, we're hardcoding the RFC-1777 BER-encodings of the various |
|
249 |
# filter types. Could pull them out into a constant. |
|
250 |
# |
|
251 |
def Filter::parse_ldap_filter obj |
|
252 |
case obj.ber_identifier |
|
253 |
when 0x87 # present. context-specific primitive 7. |
|
254 |
Filter.eq( obj.to_s, "*" ) |
|
255 |
when 0xa3 # equalityMatch. context-specific constructed 3. |
|
256 |
Filter.eq( obj[0], obj[1] ) |
|
257 |
else |
|
258 |
raise LdapError.new( "unknown ldap search-filter type: #{obj.ber_identifier}" ) |
|
259 |
end |
|
260 |
end |
|
261 | ||
262 | ||
263 |
#-- |
|
264 |
# We got a hash of attribute values. |
|
265 |
# Do we match the attributes? |
|
266 |
# Return T/F, and call match recursively as necessary. |
|
267 |
def match entry |
|
268 |
case @op |
|
269 |
when :eq |
|
270 |
if @right == "*" |
|
271 |
l = entry[@left] and l.length > 0 |
|
272 |
else |
|
273 |
l = entry[@left] and l = l.to_a and l.index(@right) |
|
274 |
end |
|
275 |
else |
|
276 |
raise LdapError.new( "unknown filter type in match: #{@op}" ) |
|
277 |
end |
|
278 |
end |
|
279 | ||
280 |
# Converts an LDAP filter-string (in the prefix syntax specified in RFC-2254) |
|
281 |
# to a Net::LDAP::Filter. |
|
282 |
def self.construct ldap_filter_string |
|
283 |
FilterParser.new(ldap_filter_string).filter |
|
284 |
end |
|
285 | ||
286 |
# Synonym for #construct. |
|
287 |
# to a Net::LDAP::Filter. |
|
288 |
def self.from_rfc2254 ldap_filter_string |
|
289 |
construct ldap_filter_string |
|
290 |
end |
|
291 | ||
292 |
end # class Net::LDAP::Filter |
|
293 | ||
294 | ||
295 | ||
296 |
class FilterParser #:nodoc: |
|
297 | ||
298 |
attr_reader :filter |
|
299 | ||
300 |
def initialize str |
|
301 |
require 'strscan' |
|
302 |
@filter = parse( StringScanner.new( str )) or raise Net::LDAP::LdapError.new( "invalid filter syntax" ) |
|
303 |
end |
|
304 | ||
305 |
def parse scanner |
|
306 |
parse_filter_branch(scanner) or parse_paren_expression(scanner) |
|
307 |
end |
|
308 | ||
309 |
def parse_paren_expression scanner |
|
310 |
if scanner.scan(/\s*\(\s*/) |
|
311 |
b = if scanner.scan(/\s*\&\s*/) |
|
312 |
a = nil |
|
313 |
branches = [] |
|
314 |
while br = parse_paren_expression(scanner) |
|
315 |
branches << br |
|
316 |
end |
|
317 |
if branches.length >= 2 |
|
318 |
a = branches.shift |
|
319 |
while branches.length > 0 |
|
320 |
a = a & branches.shift |
|
321 |
end |
|
322 |
a |
|
323 |
end |
|
324 |
elsif scanner.scan(/\s*\|\s*/) |
|
325 |
# TODO: DRY! |
|
326 |
a = nil |
|
327 |
branches = [] |
|
328 |
while br = parse_paren_expression(scanner) |
|
329 |
branches << br |
|
330 |
end |
|
331 |
if branches.length >= 2 |
|
332 |
a = branches.shift |
|
333 |
while branches.length > 0 |
|
334 |
a = a | branches.shift |
|
335 |
end |
|
336 |
a |
|
337 |
end |
|
338 |
elsif scanner.scan(/\s*\!\s*/) |
|
339 |
br = parse_paren_expression(scanner) |
|
340 |
if br |
|
341 |
~ br |
|
342 |
end |
|
343 |
else |
|
344 |
parse_filter_branch( scanner ) |
|
345 |
end |
|
346 | ||
347 |
if b and scanner.scan( /\s*\)\s*/ ) |
|
348 |
b |
|
349 |
end |
|
350 |
end |
|
351 |
end |
|
352 | ||
353 |
# Added a greatly-augmented filter contributed by Andre Nathan |
|
354 |
# for detecting special characters in values. (15Aug06) |
|
355 |
def parse_filter_branch scanner |
|
356 |
scanner.scan(/\s*/) |
|
357 |
if token = scanner.scan( /[\w\-_]+/ ) |
|
358 |
scanner.scan(/\s*/) |
|
359 |
if op = scanner.scan( /\=|\<\=|\<|\>\=|\>|\!\=/ ) |
|
360 |
scanner.scan(/\s*/) |
|
361 |
#if value = scanner.scan( /[\w\*\.]+/ ) (ORG) |
|
362 |
if value = scanner.scan( /[\w\*\.\+\-@=#\$%&!]+/ ) |
|
363 |
case op |
|
364 |
when "=" |
|
365 |
Filter.eq( token, value ) |
|
366 |
when "!=" |
|
367 |
Filter.ne( token, value ) |
|
368 |
when "<" |
|
369 |
Filter.lt( token, value ) |
|
370 |
when "<=" |
|
371 |
Filter.le( token, value ) |
|
372 |
when ">" |
|
373 |
Filter.gt( token, value ) |
|
374 |
when ">=" |
|
375 |
Filter.ge( token, value ) |
|
376 |
end |
|
377 |
end |
|
378 |
end |
|
379 |
end |
|
380 |
end |
|
381 | ||
382 |
end # class Net::LDAP::FilterParser |
|
383 | ||
384 |
end # class Net::LDAP |
|
385 |
end # module Net |
|
386 | ||
387 |
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/pdu.rb (working copy) | ||
---|---|---|
1 |
# $Id: pdu.rb 126 2006-05-31 15:55:16Z blackhedd $ |
|
2 |
# |
|
3 |
# LDAP PDU support classes |
|
4 |
# |
|
5 |
# |
|
6 |
#---------------------------------------------------------------------------- |
|
7 |
# |
|
8 |
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. |
|
9 |
# |
|
10 |
# Gmail: garbagecat10 |
|
11 |
# |
|
12 |
# This program is free software; you can redistribute it and/or modify |
|
13 |
# it under the terms of the GNU General Public License as published by |
|
14 |
# the Free Software Foundation; either version 2 of the License, or |
|
15 |
# (at your option) any later version. |
|
16 |
# |
|
17 |
# This program is distributed in the hope that it will be useful, |
|
18 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
19 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
20 |
# GNU General Public License for more details. |
|
21 |
# |
|
22 |
# You should have received a copy of the GNU General Public License |
|
23 |
# along with this program; if not, write to the Free Software |
|
24 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
25 |
# |
|
26 |
#--------------------------------------------------------------------------- |
|
27 |
# |
|
28 | ||
29 | ||
30 | ||
31 |
module Net |
|
32 | ||
33 | ||
34 |
class LdapPduError < Exception; end |
|
35 | ||
36 | ||
37 |
class LdapPdu |
|
38 | ||
39 |
BindResult = 1 |
|
40 |
SearchReturnedData = 4 |
|
41 |
SearchResult = 5 |
|
42 |
ModifyResponse = 7 |
|
43 |
AddResponse = 9 |
|
44 |
DeleteResponse = 11 |
|
45 |
ModifyRDNResponse = 13 |
|
46 |
SearchResultReferral = 19 |
|
47 | ||
48 |
attr_reader :msg_id, :app_tag |
|
49 |
attr_reader :search_dn, :search_attributes, :search_entry |
|
50 |
attr_reader :search_referrals |
|
51 | ||
52 |
# |
|
53 |
# initialize |
|
54 |
# An LDAP PDU always looks like a BerSequence with |
|
55 |
# at least two elements: an integer (message-id number), and |
|
56 |
# an application-specific sequence. |
|
57 |
# Some LDAPv3 packets also include an optional |
|
58 |
# third element, which is a sequence of "controls" |
|
59 |
# (See RFC 2251, section 4.1.12). |
|
60 |
# The application-specific tag in the sequence tells |
|
61 |
# us what kind of packet it is, and each kind has its |
|
62 |
# own format, defined in RFC-1777. |
|
63 |
# Observe that many clients (such as ldapsearch) |
|
64 |
# do not necessarily enforce the expected application |
|
65 |
# tags on received protocol packets. This implementation |
|
66 |
# does interpret the RFC strictly in this regard, and |
|
67 |
# it remains to be seen whether there are servers out |
|
68 |
# there that will not work well with our approach. |
|
69 |
# |
|
70 |
# Added a controls-processor to SearchResult. |
|
71 |
# Didn't add it everywhere because it just _feels_ |
|
72 |
# like it will need to be refactored. |
|
73 |
# |
|
74 |
def initialize ber_object |
|
75 |
begin |
|
76 |
@msg_id = ber_object[0].to_i |
|
77 |
@app_tag = ber_object[1].ber_identifier - 0x60 |
|
78 |
rescue |
|
79 |
# any error becomes a data-format error |
|
80 |
raise LdapPduError.new( "ldap-pdu format error" ) |
|
81 |
end |
|
82 | ||
83 |
case @app_tag |
|
84 |
when BindResult |
|
85 |
parse_ldap_result ber_object[1] |
|
86 |
when SearchReturnedData |
|
87 |
parse_search_return ber_object[1] |
|
88 |
when SearchResultReferral |
|
89 |
parse_search_referral ber_object[1] |
|
90 |
when SearchResult |
|
91 |
parse_ldap_result ber_object[1] |
|
92 |
parse_controls(ber_object[2]) if ber_object[2] |
|
93 |
when ModifyResponse |
|
94 |
parse_ldap_result ber_object[1] |
|
95 |
when AddResponse |
|
96 |
parse_ldap_result ber_object[1] |
|
97 |
when DeleteResponse |
|
98 |
parse_ldap_result ber_object[1] |
|
99 |
when ModifyRDNResponse |
|
100 |
parse_ldap_result ber_object[1] |
|
101 |
else |
|
102 |
raise LdapPduError.new( "unknown pdu-type: #{@app_tag}" ) |
|
103 |
end |
|
104 |
end |
|
105 | ||
106 |
# |
|
107 |
# result_code |
|
108 |
# This returns an LDAP result code taken from the PDU, |
|
109 |
# but it will be nil if there wasn't a result code. |
|
110 |
# That can easily happen depending on the type of packet. |
|
111 |
# |
|
112 |
def result_code code = :resultCode |
|
113 |
@ldap_result and @ldap_result[code] |
|
114 |
end |
|
115 | ||
116 |
# Return RFC-2251 Controls if any. |
|
117 |
# Messy. Does this functionality belong somewhere else? |
|
118 |
def result_controls |
|
119 |
@ldap_controls || [] |
|
120 |
end |
|
121 | ||
122 | ||
123 |
# |
|
124 |
# parse_ldap_result |
|
125 |
# |
|
126 |
def parse_ldap_result sequence |
|
127 |
sequence.length >= 3 or raise LdapPduError |
|
128 |
@ldap_result = {:resultCode => sequence[0], :matchedDN => sequence[1], :errorMessage => sequence[2]} |
|
129 |
end |
|
130 |
private :parse_ldap_result |
|
131 | ||
132 |
# |
|
133 |
# parse_search_return |
|
134 |
# Definition from RFC 1777 (we're handling application-4 here) |
|
135 |
# |
|
136 |
# Search Response ::= |
|
137 |
# CHOICE { |
|
138 |
# entry [APPLICATION 4] SEQUENCE { |
|
139 |
# objectName LDAPDN, |
|
140 |
# attributes SEQUENCE OF SEQUENCE { |
|
141 |
# AttributeType, |
|
142 |
# SET OF AttributeValue |
|
143 |
# } |
|
144 |
# }, |
|
145 |
# resultCode [APPLICATION 5] LDAPResult |
|
146 |
# } |
|
147 |
# |
|
148 |
# We concoct a search response that is a hash of the returned attribute values. |
|
149 |
# NOW OBSERVE CAREFULLY: WE ARE DOWNCASING THE RETURNED ATTRIBUTE NAMES. |
|
150 |
# This is to make them more predictable for user programs, but it |
|
151 |
# may not be a good idea. Maybe this should be configurable. |
|
152 |
# ALTERNATE IMPLEMENTATION: In addition to @search_dn and @search_attributes, |
|
153 |
# we also return @search_entry, which is an LDAP::Entry object. |
|
154 |
# If that works out well, then we'll remove the first two. |
|
155 |
# |
|
156 |
# Provisionally removed obsolete search_attributes and search_dn, 04May06. |
|
157 |
# |
|
158 |
def parse_search_return sequence |
|
159 |
sequence.length >= 2 or raise LdapPduError |
|
160 |
@search_entry = LDAP::Entry.new( sequence[0] ) |
|
161 |
#@search_dn = sequence[0] |
|
162 |
#@search_attributes = {} |
|
163 |
sequence[1].each {|seq| |
|
164 |
@search_entry[seq[0]] = seq[1] |
|
165 |
#@search_attributes[seq[0].downcase.intern] = seq[1] |
|
166 |
} |
|
167 |
end |
|
168 | ||
169 |
# |
|
170 |
# A search referral is a sequence of one or more LDAP URIs. |
|
171 |
# Any number of search-referral replies can be returned by the server, interspersed |
|
172 |
# with normal replies in any order. |
|
173 |
# Until I can think of a better way to do this, we'll return the referrals as an array. |
|
174 |
# It'll be up to higher-level handlers to expose something reasonable to the client. |
|
175 |
def parse_search_referral uris |
|
176 |
@search_referrals = uris |
|
177 |
end |
|
178 | ||
179 | ||
180 |
# Per RFC 2251, an LDAP "control" is a sequence of tuples, each consisting |
|
181 |
# of an OID, a boolean criticality flag defaulting FALSE, and an OPTIONAL |
|
182 |
# Octet String. If only two fields are given, the second one may be |
|
183 |
# either criticality or data, since criticality has a default value. |
|
184 |
# Someday we may want to come back here and add support for some of |
|
185 |
# more-widely used controls. RFC-2696 is a good example. |
|
186 |
# |
|
187 |
def parse_controls sequence |
|
188 |
@ldap_controls = sequence.map do |control| |
|
189 |
o = OpenStruct.new |
|
190 |
o.oid,o.criticality,o.value = control[0],control[1],control[2] |
|
191 |
if o.criticality and o.criticality.is_a?(String) |
|
192 |
o.value = o.criticality |
|
193 |
o.criticality = false |
|
194 |
end |
|
195 |
o |
|
196 |
end |
|
197 |
end |
|
198 |
private :parse_controls |
|
199 | ||
200 | ||
201 |
end |
|
202 | ||
203 | ||
204 |
end # module Net |
|
205 |
vendor/plugins/ruby-net-ldap-0.0.4/lib/net/ldap/psw.rb (working copy) | ||
---|---|---|
1 |
# $Id: psw.rb 73 2006-04-24 21:59:35Z blackhedd $ |
|
2 |
# |
|
3 |
# |
|
4 |
#---------------------------------------------------------------------------- |
|
5 |
# |
|
6 |
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. |
|
7 |
# |
|
8 |
# Gmail: garbagecat10 |
|
9 |
# |
|
10 |
# This program is free software; you can redistribute it and/or modify |
|
11 |
# it under the terms of the GNU General Public License as published by |
|
12 |
# the Free Software Foundation; either version 2 of the License, or |
|
13 |
# (at your option) any later version. |
|
14 |
# |
|
15 |
# This program is distributed in the hope that it will be useful, |
|
16 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
18 |
# GNU General Public License for more details. |
|
19 |
# |
|
20 |
# You should have received a copy of the GNU General Public License |
|
21 |
# along with this program; if not, write to the Free Software |
|
22 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
23 |
# |
|
24 |
#--------------------------------------------------------------------------- |
|
25 |
# |
|
26 |
# |
|
27 | ||
28 | ||
29 |
module Net |
|
30 |
class LDAP |
|
31 | ||
32 | ||
33 |
class Password |
|
34 |
class << self |
|
35 | ||
36 |
# Generate a password-hash suitable for inclusion in an LDAP attribute. |
|
37 |
# Pass a hash type (currently supported: :md5 and :sha) and a plaintext |
- « Previous
- 1
- 2
- 3
- 4
- Next »