fakeldap 0.0.1 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +7 -1
  3. data/lib/fakeldap.rb +133 -10
  4. data/lib/fakeldap/version.rb +1 -1
  5. metadata +50 -191
  6. data/vendor/ruby-ldapserver/COPYING +0 -27
  7. data/vendor/ruby-ldapserver/ChangeLog +0 -83
  8. data/vendor/ruby-ldapserver/Manifest.txt +0 -32
  9. data/vendor/ruby-ldapserver/README +0 -222
  10. data/vendor/ruby-ldapserver/Rakefile +0 -22
  11. data/vendor/ruby-ldapserver/doc/LDAP.html +0 -104
  12. data/vendor/ruby-ldapserver/doc/LDAP/Abandon.html +0 -112
  13. data/vendor/ruby-ldapserver/doc/LDAP/Error.html +0 -115
  14. data/vendor/ruby-ldapserver/doc/LDAP/ResultError.html +0 -241
  15. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AdminLimitExceeded.html +0 -158
  16. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AffectsMultipleDSAs.html +0 -158
  17. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AliasDereferencingProblem.html +0 -158
  18. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AliasProblem.html +0 -158
  19. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AttributeOrValueExists.html +0 -158
  20. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/AuthMethodNotSupported.html +0 -158
  21. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Busy.html +0 -158
  22. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/CompareFalse.html +0 -158
  23. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/CompareTrue.html +0 -158
  24. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ConfidentialityRequired.html +0 -158
  25. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ConstraintViolation.html +0 -158
  26. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/EntryAlreadyExists.html +0 -158
  27. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InappropriateAuthentication.html +0 -158
  28. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InappropriateMatching.html +0 -158
  29. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InsufficientAccessRights.html +0 -158
  30. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InvalidAttributeSyntax.html +0 -158
  31. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InvalidCredentials.html +0 -158
  32. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/InvalidDNSyntax.html +0 -158
  33. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/IsLeaf.html +0 -158
  34. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/LoopDetect.html +0 -158
  35. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NamingViolation.html +0 -158
  36. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NoSuchAttribute.html +0 -158
  37. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NoSuchObject.html +0 -158
  38. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NotAllowedOnNonLeaf.html +0 -158
  39. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/NotAllowedOnRDN.html +0 -158
  40. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ObjectClassModsProhibited.html +0 -158
  41. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ObjectClassViolation.html +0 -158
  42. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/OperationsError.html +0 -158
  43. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Other.html +0 -158
  44. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/ProtocolError.html +0 -158
  45. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Referral.html +0 -158
  46. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/SaslBindInProgress.html +0 -158
  47. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/SizeLimitExceeded.html +0 -158
  48. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/StrongAuthRequired.html +0 -158
  49. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Success.html +0 -158
  50. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/TimeLimitExceeded.html +0 -158
  51. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/Unavailable.html +0 -158
  52. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/UnavailableCriticalExtension.html +0 -158
  53. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/UndefinedAttributeType.html +0 -158
  54. data/vendor/ruby-ldapserver/doc/LDAP/ResultError/UnwillingToPerform.html +0 -158
  55. data/vendor/ruby-ldapserver/doc/LDAP/Server.html +0 -1056
  56. data/vendor/ruby-ldapserver/doc/LDAP/Server/Connection.html +0 -1353
  57. data/vendor/ruby-ldapserver/doc/LDAP/Server/Filter.html +0 -634
  58. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule.html +0 -1132
  59. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/DefaultMatchingClass.html +0 -219
  60. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/Equality.html +0 -170
  61. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/IA5Downcase.html +0 -143
  62. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/IA5Trim.html +0 -155
  63. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/Integer.html +0 -143
  64. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/Ordering.html +0 -212
  65. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/StringDowncase.html +0 -143
  66. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/StringTrim.html +0 -154
  67. data/vendor/ruby-ldapserver/doc/LDAP/Server/MatchingRule/Substrings.html +0 -177
  68. data/vendor/ruby-ldapserver/doc/LDAP/Server/Operation.html +0 -2994
  69. data/vendor/ruby-ldapserver/doc/LDAP/Server/Schema.html +0 -2024
  70. data/vendor/ruby-ldapserver/doc/LDAP/Server/Schema/AttributeType.html +0 -1462
  71. data/vendor/ruby-ldapserver/doc/LDAP/Server/Schema/ObjectClass.html +0 -1097
  72. data/vendor/ruby-ldapserver/doc/LDAP/Server/Syntax.html +0 -1254
  73. data/vendor/ruby-ldapserver/doc/LDAP/Server/VERSION.html +0 -134
  74. data/vendor/ruby-ldapserver/doc/_index.html +0 -662
  75. data/vendor/ruby-ldapserver/doc/class_list.html +0 -36
  76. data/vendor/ruby-ldapserver/doc/css/common.css +0 -1
  77. data/vendor/ruby-ldapserver/doc/css/full_list.css +0 -50
  78. data/vendor/ruby-ldapserver/doc/css/style.css +0 -303
  79. data/vendor/ruby-ldapserver/doc/file.README.html +0 -399
  80. data/vendor/ruby-ldapserver/doc/file_list.html +0 -38
  81. data/vendor/ruby-ldapserver/doc/frames.html +0 -13
  82. data/vendor/ruby-ldapserver/doc/index.html +0 -399
  83. data/vendor/ruby-ldapserver/doc/js/app.js +0 -204
  84. data/vendor/ruby-ldapserver/doc/js/full_list.js +0 -112
  85. data/vendor/ruby-ldapserver/doc/js/jquery.js +0 -154
  86. data/vendor/ruby-ldapserver/doc/method_list.html +0 -1571
  87. data/vendor/ruby-ldapserver/doc/top-level-namespace.html +0 -88
  88. data/vendor/ruby-ldapserver/examples/README +0 -89
  89. data/vendor/ruby-ldapserver/examples/mkcert.rb +0 -31
  90. data/vendor/ruby-ldapserver/examples/rbslapd1.rb +0 -111
  91. data/vendor/ruby-ldapserver/examples/rbslapd2.rb +0 -161
  92. data/vendor/ruby-ldapserver/examples/rbslapd3.rb +0 -172
  93. data/vendor/ruby-ldapserver/examples/speedtest.rb +0 -37
  94. data/vendor/ruby-ldapserver/lib/ldap/server.rb +0 -4
  95. data/vendor/ruby-ldapserver/lib/ldap/server/connection.rb +0 -276
  96. data/vendor/ruby-ldapserver/lib/ldap/server/filter.rb +0 -223
  97. data/vendor/ruby-ldapserver/lib/ldap/server/match.rb +0 -283
  98. data/vendor/ruby-ldapserver/lib/ldap/server/operation.rb +0 -487
  99. data/vendor/ruby-ldapserver/lib/ldap/server/preforkserver.rb +0 -93
  100. data/vendor/ruby-ldapserver/lib/ldap/server/result.rb +0 -71
  101. data/vendor/ruby-ldapserver/lib/ldap/server/schema.rb +0 -592
  102. data/vendor/ruby-ldapserver/lib/ldap/server/server.rb +0 -89
  103. data/vendor/ruby-ldapserver/lib/ldap/server/syntax.rb +0 -235
  104. data/vendor/ruby-ldapserver/lib/ldap/server/tcpserver.rb +0 -91
  105. data/vendor/ruby-ldapserver/lib/ldap/server/util.rb +0 -88
  106. data/vendor/ruby-ldapserver/lib/ldap/server/version.rb +0 -11
  107. data/vendor/ruby-ldapserver/test/core.schema +0 -582
  108. data/vendor/ruby-ldapserver/test/encoding_test.rb +0 -279
  109. data/vendor/ruby-ldapserver/test/filter_test.rb +0 -107
  110. data/vendor/ruby-ldapserver/test/match_test.rb +0 -59
  111. data/vendor/ruby-ldapserver/test/schema_test.rb +0 -113
  112. data/vendor/ruby-ldapserver/test/syntax_test.rb +0 -40
  113. data/vendor/ruby-ldapserver/test/test_helper.rb +0 -2
  114. data/vendor/ruby-ldapserver/test/util_test.rb +0 -51
@@ -1,88 +0,0 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
- <head>
5
- <meta name="Content-Type" content="text/html; charset=utf-8" />
6
- <title>Top Level Namespace</title>
7
- <link rel="stylesheet" href="css/style.css" type="text/css" media="screen" charset="utf-8" />
8
- <link rel="stylesheet" href="css/common.css" type="text/css" media="screen" charset="utf-8" />
9
-
10
- <script type="text/javascript" charset="utf-8">
11
- relpath = '';
12
- if (relpath != '') relpath += '/';
13
- </script>
14
- <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
15
- <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
16
-
17
- </head>
18
- <body>
19
- <script type="text/javascript" charset="utf-8">
20
- if (window.top.frames.main) document.body.className = 'frames';
21
- </script>
22
-
23
- <div id="header">
24
- <div id="menu">
25
-
26
- <a href="_index.html">Index</a> &raquo;
27
-
28
-
29
- <span class="title">Top Level Namespace</span>
30
-
31
-
32
- <div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
33
- </div>
34
-
35
- <div id="search">
36
- <a id="class_list_link" href="#">Class List</a>
37
- <a id="method_list_link" href="#">Method List</a>
38
- <a id ="file_list_link" href="#">File List</a>
39
- </div>
40
-
41
- <div class="clear"></div>
42
- </div>
43
-
44
- <iframe id="search_frame"></iframe>
45
-
46
- <div id="content"><h1>Top Level Namespace
47
-
48
-
49
-
50
- </h1>
51
-
52
- <dl class="box">
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
- </dl>
62
- <div class="clear"></div>
63
-
64
- <h2>Defined Under Namespace</h2>
65
- <p class="children">
66
-
67
-
68
- <strong class="modules">Modules:</strong> <span class='object_link'><a href="LDAP.html" title="LDAP (module)">LDAP</a></span>
69
-
70
-
71
-
72
-
73
- </p>
74
-
75
-
76
-
77
-
78
-
79
- </div>
80
-
81
- <div id="footer">
82
- Generated on Mon Sep 13 13:27:18 2010 by
83
- <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
84
- 0.6.0 (ruby-1.9.2).
85
- </div>
86
-
87
- </body>
88
- </html>
@@ -1,89 +0,0 @@
1
- Using the example programs
2
- ==========================
3
-
4
- These servers all listen on port 1389 by default, so that they don't have to
5
- be run as root.
6
-
7
- Example 1: trivial server using RAM hash
8
- ----------------------------------------
9
-
10
- $ ruby rbslapd1.rb
11
-
12
- In another window:
13
-
14
- $ ldapadd -H ldap://127.0.0.1:1389/
15
- dn: dc=example,dc=com
16
- cn: Top object
17
-
18
- dn: cn=Fred Flintstone,dc=example,dc=com
19
- cn: Fred Flintstone
20
- sn: Flintstone
21
- mail: fred@bedrock.org
22
- mail: fred.flintstone@bedrock.org
23
-
24
- dn: cn=Wilma Flintstone,dc=example,dc=com
25
- cn: Wilma Flintstone
26
- mail: wilma@bedrock.org
27
- ^D
28
-
29
- Try these queries:
30
-
31
- $ ldapsearch -H ldap://127.0.0.1:1389/ -b "" "(objectclass=*)"
32
- $ ldapsearch -H ldap://127.0.0.1:1389/ -b "dc=example,dc=com" -s base "(objectclass=*)"
33
- $ ldapsearch -H ldap://127.0.0.1:1389/ -b "dc=example,dc=com" "(mail=fred*)"
34
-
35
- If you terminate the server with Ctrl-C, its contents should be written
36
- to disk as a YAML file.
37
-
38
- A fairly complete set of the filter language is implemented. However, this
39
- simple server works by simply scanning the entire database and applying the
40
- filter to each entry, so it won't scale to large applications. No validation
41
- of DN or attributes against any sort of schema is done.
42
-
43
- Example 1a: with SSL
44
- --------------------
45
-
46
- In rbslapd1.rb, uncomment
47
-
48
- :ssl_key_file => "key.pem",
49
- :ssl_cert_file => "cert.pem",
50
- :ssl_on_connect => true,
51
-
52
- and run mkcert.rb. Since this is a self-signed certificate, you'll have to
53
- turn off certificate verification in the client too. For example:
54
-
55
- $ env LDAPTLS_REQCERT="allow" ldapsearch -H ldaps://127.0.0.1:1389/
56
-
57
- Making your own CA and installing its certificate in the client, or
58
- generating a Certificate Signing Request and sending it to a known CA, is
59
- beyond the scope of this documentation.
60
-
61
- Example 2: simple LDAP to SQL mapping
62
- -------------------------------------
63
-
64
- You will need to set up a MySQL database with a table conforming to the
65
- schema given within the code. Once done, LDAP gives a read-only view of the
66
- database with only the filter "(uid=<foo>)" supported.
67
-
68
- Example 3: preforking server and schema
69
- ---------------------------------------
70
-
71
- This functions in the same way as rbslapd1.rb. However, since each query is
72
- answered in a separate process, the YAML file on disk is used as the master
73
- repository. Update operations re-write this file each time.
74
-
75
- Also, the schema is read from file 'core.schema'. Attempting to insert the
76
- above entries will fail, due to schema violations. Insert a valid entry,
77
- e.g.
78
-
79
- dn: cn=Fred Flintstone,dc=example,dc=com
80
- objectClass: organizationalPerson
81
- cn: Fred Flintstone
82
- sn: Flintstone
83
- telephoneNumber: +1 555 1234
84
- telephoneNumber: +1 555 5432
85
-
86
- Schema validation takes place for the attribute values and that attributes
87
- are allowed/required by the objectclass(es); however, the DN itself is not
88
- validated, nor any checks made that the RDN is present as an attribute
89
- (since this is one of the more stupid parts of the LDAP/X500 data model)
@@ -1,31 +0,0 @@
1
- require 'openssl'
2
-
3
- # Taken directly from echo_svr.rb in the Ruby openssl examples
4
-
5
- key = OpenSSL::PKey::RSA.new(1024){ print "."; $stdout.flush }
6
- puts
7
- cert = OpenSSL::X509::Certificate.new
8
- cert.version = 2
9
- cert.serial = 0
10
- name = OpenSSL::X509::Name.new([["C","JP"],["O","TEST"],["CN","localhost"]])
11
- cert.subject = name
12
- cert.issuer = name
13
- cert.not_before = Time.now
14
- cert.not_after = Time.now + 3600
15
- cert.public_key = key.public_key
16
- ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
17
- cert.extensions = [
18
- ef.create_extension("basicConstraints","CA:FALSE"),
19
- ef.create_extension("subjectKeyIdentifier","hash"),
20
- ef.create_extension("extendedKeyUsage","serverAuth"),
21
- ef.create_extension("keyUsage",
22
- "keyEncipherment,dataEncipherment,digitalSignature")
23
- ]
24
- ef.issuer_certificate = cert
25
- cert.add_extension ef.create_extension("authorityKeyIdentifier",
26
- "keyid:always,issuer:always")
27
- cert.sign(key, OpenSSL::Digest::SHA1.new)
28
-
29
- # Write to disk
30
- File.open("key.pem","w",0600) { |f| f << key.to_pem }
31
- File.open("cert.pem","w",0644) { |f| f << cert.to_pem }
@@ -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
@@ -1,161 +0,0 @@
1
- #!/usr/local/bin/ruby -w
2
-
3
- $:.unshift('../lib')
4
- require 'ldap/server'
5
- require 'mysql' # <http://www.tmtm.org/en/ruby/mysql/>
6
- require 'thread'
7
- require 'resolv-replace' # ruby threading DNS client
8
-
9
- # An example of an LDAP to SQL gateway. We have a MySQL table which
10
- # contains (login_id,login,passwd) combinations, e.g.
11
- #
12
- # +----------+----------+--------+
13
- # | login_id | login | passwd |
14
- # +----------+----------+--------+
15
- # | 1 | brian | foobar |
16
- # | 2 | caroline | boing |
17
- # +----------+----------+--------+
18
- #
19
- # We support LDAP searches for (uid=login), returning a synthesised DN and
20
- # Maildir attribute, and we support LDAP binds to validate passwords. We
21
- # keep a cache of recent lookups so that a bind to validate a password
22
- # doesn't cause a second SQL query. Since we're multi-threaded, this should
23
- # work even if the bind occurs on a different client connection to the search.
24
- #
25
- # To test:
26
- # ldapsearch -H ldap://127.0.0.1:1389/ -b "dc=example,dc=com" "(uid=brian)"
27
- #
28
- # ldapsearch -H ldap://127.0.0.1:1389/ -b "dc=example,dc=com" \
29
- # -D "id=1,dc=example,dc=com" -W "(uid=brian)"
30
-
31
- $debug = true
32
- SQL_CONNECT = ["1.2.3.4", "myuser", "mypass", "mydb"]
33
- TABLE = "logins"
34
- SQL_POOL_SIZE = 5
35
- PW_CACHE_SIZE = 100
36
- BASEDN = "dc=example,dc=com"
37
- LDAP_PORT = 1389
38
-
39
- # A thread-safe pool of persistent MySQL connections
40
-
41
- class SQLPool
42
- def initialize(n, *args)
43
- @args = args
44
- @pool = Queue.new # this is a thread-safe queue
45
- n.times { @pool.push nil } # create connections on demand
46
- end
47
-
48
- def borrow
49
- conn = @pool.pop || Mysql::new(*@args)
50
- yield conn
51
- rescue Exception
52
- conn = nil # put 'nil' back into the pool
53
- raise
54
- ensure
55
- @pool.push conn
56
- end
57
- end
58
-
59
- # An simple LRU cache of username->password. It's linearly searched
60
- # so don't make it too big.
61
-
62
- class LRUCache
63
- def initialize(size)
64
- @size = size
65
- @cache = [] # [[key,val],[key,val],...]
66
- @mutex = Mutex.new
67
- end
68
-
69
- def add(id,data)
70
- @mutex.synchronize do
71
- @cache.delete_if { |k,v| k == id }
72
- @cache.unshift [id,data]
73
- @cache.pop while @cache.size > @size
74
- end
75
- end
76
-
77
- def find(id)
78
- @mutex.synchronize do
79
- index = entry = nil
80
- @cache.each_with_index do |e, i|
81
- if e[0] == id
82
- entry = e
83
- index = i
84
- break
85
- end
86
- end
87
- return nil unless index
88
- @cache.delete_at(index)
89
- @cache.unshift entry
90
- return entry[1]
91
- end
92
- end
93
- end
94
-
95
-
96
- class SQLOperation < LDAP::Server::Operation
97
- def self.setcache(cache,pool)
98
- @@cache = cache
99
- @@pool = pool
100
- end
101
-
102
- # Handle searches of the form "(uid=<foo>)" using SQL backend
103
- # (uid=foo) => [:eq, "uid", matchobj, "foo"]
104
-
105
- def search(basedn, scope, deref, filter)
106
- raise LDAP::ResultError::UnwillingToPerform, "Bad base DN" unless basedn == BASEDN
107
- raise LDAP::ResultError::UnwillingToPerform, "Bad filter" unless filter[0..1] == [:eq, "uid"]
108
- uid = filter[3]
109
- @@pool.borrow do |sql|
110
- q = "select login_id,passwd from #{TABLE} where login='#{sql.quote(uid)}'"
111
- puts "SQL Query #{sql.object_id}: #{q}" if $debug
112
- res = sql.query(q)
113
- res.each do |login_id,passwd|
114
- @@cache.add(login_id, passwd)
115
- send_SearchResultEntry("id=#{login_id},#{BASEDN}", {
116
- "maildir"=>["/netapp/#{uid}/"],
117
- })
118
- end
119
- end
120
- end
121
-
122
- # Validate passwords
123
-
124
- def simple_bind(version, dn, password)
125
- return if dn.nil? # accept anonymous
126
-
127
- raise LDAP::ResultError::UnwillingToPerform unless dn =~ /\Aid=(\d+),#{BASEDN}\z/
128
- login_id = $1
129
- dbpw = @@cache.find(login_id)
130
- unless dbpw
131
- @@pool.borrow do |sql|
132
- q = "select passwd from #{TABLE} where login_id=#{login_id}"
133
- puts "SQL Query #{sql.object_id}: #{q}" if $debug
134
- res = sql.query(q)
135
- if res.num_rows == 1
136
- dbpw = res.fetch_row[0]
137
- @@cache.add(login_id, dbpw)
138
- end
139
- end
140
- end
141
- raise LDAP::ResultError::InvalidCredentials unless dbpw and dbpw != "" and dbpw == password
142
- end
143
- end
144
-
145
- # Build the objects we need
146
-
147
- cache = LRUCache.new(PW_CACHE_SIZE)
148
- pool = SQLPool.new(SQL_POOL_SIZE, *SQL_CONNECT)
149
- SQLOperation.setcache(cache,pool)
150
-
151
- s = LDAP::Server.new(
152
- :port => LDAP_PORT,
153
- :nodelay => true,
154
- :listen => 10,
155
- # :ssl_key_file => "key.pem",
156
- # :ssl_cert_file => "cert.pem",
157
- # :ssl_on_connect => true,
158
- :operation_class => SQLOperation
159
- )
160
- s.run_tcpserver
161
- s.join