ldaptic 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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