ldaptic 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/test/rbslapd1.rb DELETED
@@ -1,111 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
-
3
- # This is a trivial LDAP server which just stores directory entries in RAM.
4
- # It does no validation or authentication. This is intended just to
5
- # demonstrate the API, it's not for real-world use!!
6
-
7
- $:.unshift('../lib')
8
- $debug = true
9
-
10
- require 'ldap/server'
11
-
12
- # We subclass the Operation class, overriding the methods to do what we need
13
-
14
- class HashOperation < LDAP::Server::Operation
15
- def initialize(connection, messageID, hash)
16
- super(connection, messageID)
17
- @hash = hash # an object reference to our directory data
18
- end
19
-
20
- def search(basedn, scope, deref, filter)
21
- basedn.downcase!
22
-
23
- case scope
24
- when LDAP::Server::BaseObject
25
- # client asked for single object by DN
26
- obj = @hash[basedn]
27
- raise LDAP::ResultError::NoSuchObject unless obj
28
- send_SearchResultEntry(basedn, obj) if LDAP::Server::Filter.run(filter, obj)
29
-
30
- when LDAP::Server::WholeSubtree
31
- @hash.each do |dn, av|
32
- next unless dn.index(basedn, -basedn.length) # under basedn?
33
- next unless LDAP::Server::Filter.run(filter, av) # attribute filter?
34
- send_SearchResultEntry(dn, av)
35
- end
36
-
37
- else
38
- raise LDAP::ResultError::UnwillingToPerform, "OneLevel not implemented"
39
-
40
- end
41
- end
42
-
43
- def add(dn, av)
44
- dn.downcase!
45
- raise LDAP::ResultError::EntryAlreadyExists if @hash[dn]
46
- @hash[dn] = av
47
- end
48
-
49
- def del(dn)
50
- dn.downcase!
51
- raise LDAP::ResultError::NoSuchObject unless @hash.has_key?(dn)
52
- @hash.delete(dn)
53
- end
54
-
55
- def modify(dn, ops)
56
- entry = @hash[dn]
57
- raise LDAP::ResultError::NoSuchObject unless entry
58
- ops.each do |attr, vals|
59
- op = vals.shift
60
- case op
61
- when :add
62
- entry[attr] ||= []
63
- entry[attr] += vals
64
- entry[attr].uniq!
65
- when :delete
66
- if vals == []
67
- entry.delete(attr)
68
- else
69
- vals.each { |v| entry[attr].delete(v) }
70
- end
71
- when :replace
72
- entry[attr] = vals
73
- end
74
- entry.delete(attr) if entry[attr] == []
75
- end
76
- end
77
- end
78
-
79
- # This is the shared object which carries our actual directory entries.
80
- # It's just a hash of {dn=>entry}, where each entry is {attr=>[val,val,...]}
81
-
82
- directory = {}
83
-
84
- # Let's put some backing store on it
85
-
86
- require 'yaml'
87
- begin
88
- File.open("ldapdb.yaml") { |f| directory = YAML::load(f.read) }
89
- rescue Errno::ENOENT
90
- end
91
-
92
- at_exit do
93
- File.open("ldapdb.new","w") { |f| f.write(YAML::dump(directory)) }
94
- File.rename("ldapdb.new","ldapdb.yaml")
95
- end
96
-
97
- # Listen for incoming LDAP connections. For each one, create a Connection
98
- # object, which will invoke a HashOperation object for each request.
99
-
100
- s = LDAP::Server.new(
101
- :port => 1389,
102
- :nodelay => true,
103
- :listen => 10,
104
- # :ssl_key_file => "key.pem",
105
- # :ssl_cert_file => "cert.pem",
106
- # :ssl_on_connect => true,
107
- :operation_class => HashOperation,
108
- :operation_args => [directory]
109
- )
110
- s.run_tcpserver
111
- s.join
data/test/rbslapd4.rb DELETED
@@ -1,172 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
-
3
- # This is similar to rbslapd1.rb but here we use TOMITA Masahiro's prefork
4
- # library: <http://raa.ruby-lang.org/project/prefork/>
5
- # Advantages over Ruby threading:
6
- # - each client connection is handled in its own process; don't need
7
- # to worry about Ruby thread blocking (except if one client issues
8
- # overlapping LDAP operations down the same connection, which is uncommon)
9
- # - better scalability on multi-processor systems
10
- # - better scalability on single-processor systems (e.g. shouldn't hit
11
- # max FDs per process limit)
12
- # Disadvantages:
13
- # - client connections can't share state in RAM. So our shared directory
14
- # now has to be read from disk, and flushed to disk after every update.
15
- #
16
- # Additionally, I have added schema support. An LDAP v3 client can
17
- # query the schema remotely, and adds/modifies have data validated.
18
-
19
- $:.unshift('../lib')
20
-
21
- require 'ldap/server'
22
- require 'ldap/server/schema'
23
- require 'yaml'
24
-
25
- $debug = nil # $stderr
26
-
27
- # An object to keep our in-RAM database and synchronise it to disk
28
- # when necessary
29
-
30
- class Directory
31
- attr_reader :data
32
-
33
- def initialize(filename)
34
- @filename = filename
35
- @stat = nil
36
- update
37
- end
38
-
39
- # synchronise with directory on disk (re-read if it has changed)
40
-
41
- def update
42
- begin
43
- tmp = {}
44
- sb = File.stat(@filename)
45
- return if @stat and @stat.ino == sb.ino and @stat.mtime == sb.mtime
46
- File.open(@filename) do |f|
47
- tmp = YAML::load(f.read)
48
- @stat = f.stat
49
- end
50
- rescue Errno::ENOENT
51
- end
52
- @data = tmp
53
- end
54
-
55
- # write back to disk
56
-
57
- def write
58
- File.open(@filename+".new","w") { |f| f.write(YAML::dump(@data)) }
59
- File.rename(@filename+".new",@filename)
60
- @stat = File.stat(@filename)
61
- end
62
-
63
- # run a block while holding a lock on the database
64
-
65
- def lock
66
- File.open(@filename+".lock","w") do |f|
67
- f.flock(File::LOCK_EX) # will block here until lock available
68
- yield
69
- end
70
- end
71
- end
72
-
73
- # We subclass the Operation class, overriding the methods to do what we need
74
-
75
- class DirOperation < LDAP::Server::Operation
76
- def initialize(connection, messageID, dir)
77
- super(connection, messageID)
78
- @dir = dir
79
- end
80
-
81
- def search(basedn, scope, deref, filter)
82
- $debug << "Search: basedn=#{basedn.inspect}, scope=#{scope.inspect}, deref=#{deref.inspect}, filter=#{filter.inspect}\n" if $debug
83
- basedn.downcase!
84
-
85
- case scope
86
- when LDAP::Server::BaseObject
87
- # client asked for single object by DN
88
- @dir.update
89
- obj = @dir.data[basedn]
90
- raise LDAP::ResultError::NoSuchObject unless obj
91
- ok = LDAP::Server::Filter.run(filter, obj)
92
- $debug << "Match=#{ok.inspect}: #{obj.inspect}\n" if $debug
93
- send_SearchResultEntry(basedn, obj) if ok
94
-
95
- when LDAP::Server::WholeSubtree
96
- @dir.update
97
- @dir.data.each do |dn, av|
98
- $debug << "Considering #{dn}\n" if $debug
99
- next unless dn.index(basedn, -basedn.length) # under basedn?
100
- next unless LDAP::Server::Filter.run(filter, av) # attribute filter?
101
- $debug << "Sending: #{av.inspect}\n" if $debug
102
- send_SearchResultEntry(dn, av)
103
- end
104
-
105
- else
106
- raise LDAP::ResultError::UnwillingToPerform, "OneLevel not implemented"
107
-
108
- end
109
- end
110
-
111
- def add(dn, entry)
112
- entry = @schema.validate(entry)
113
- entry['createTimestamp'] = [Time.now.gmtime.strftime("%Y%m%d%H%MZ")]
114
- entry['creatorsName'] = [@connection.binddn.to_s]
115
- # FIXME: normalize the DN and check it's below our root DN
116
- # FIXME: validate that a superior object exists
117
- # FIXME: validate that entry contains the RDN attribute (yuk)
118
- dn.downcase!
119
- @dir.lock do
120
- @dir.update
121
- raise LDAP::ResultError::EntryAlreadyExists if @dir.data[dn]
122
- @dir.data[dn] = entry
123
- @dir.write
124
- end
125
- end
126
-
127
- def del(dn)
128
- dn.downcase!
129
- @dir.lock do
130
- @dir.update
131
- raise LDAP::ResultError::NoSuchObject unless @dir.data.has_key?(dn)
132
- @dir.data.delete(dn)
133
- @dir.write
134
- end
135
- end
136
-
137
- def modify(dn, ops)
138
- dn.downcase!
139
- @dir.lock do
140
- @dir.update
141
- entry = @dir.data[dn]
142
- raise LDAP::ResultError::NoSuchObject unless entry
143
- entry = @schema.validate(ops, entry) # also does the update
144
- entry['modifyTimestamp'] = [Time.now.gmtime.strftime("%Y%m%d%H%MZ")]
145
- entry['modifiersName'] = [@connection.binddn.to_s]
146
- @dir.data[dn] = entry
147
- @dir.write
148
- end
149
- end
150
- end
151
-
152
- directory = Directory.new("ldapdb.yaml")
153
-
154
- schema = LDAP::Server::Schema.new
155
- schema.load_system
156
- schema.load_file("../test/core.schema")
157
- schema.resolve_oids
158
-
159
- s = LDAP::Server.new(
160
- :port => 1389,
161
- :nodelay => true,
162
- :listen => 10,
163
- # :ssl_key_file => "key.pem",
164
- # :ssl_cert_file => "cert.pem",
165
- # :ssl_on_connect => true,
166
- :operation_class => DirOperation,
167
- :operation_args => [directory],
168
- :schema => schema,
169
- :namingContexts => ['dc=example,dc=com']
170
- )
171
- s.run_tcpserver
172
- s.join