jruby-ldap-patched 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/History.txt +7 -0
- data/LICENSE +20 -0
- data/README +14 -0
- data/Rakefile +14 -0
- data/jruby-ldap.gemspec +20 -0
- data/lib/jruby-ldap.rb +7 -0
- data/lib/jruby-ldap/version.rb +5 -0
- data/lib/ldap.rb +83 -0
- data/lib/ldap/conn.rb +285 -0
- data/lib/ldap/constants.rb +126 -0
- data/lib/ldap/control.rb +48 -0
- data/lib/ldap/entry.rb +64 -0
- data/lib/ldap/error.rb +14 -0
- data/lib/ldap/ldif.rb +567 -0
- data/lib/ldap/mod.rb +74 -0
- data/lib/ldap/schema.rb +131 -0
- data/test/setup.rb +52 -0
- data/test/test_add.rb +21 -0
- data/test/test_connection.rb +52 -0
- data/test/test_delete.rb +21 -0
- data/test/test_search.rb +87 -0
- data/test/test_ssl.rb +21 -0
- metadata +88 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: '0080239062c69814c70892ff187d97b2a34126bd'
|
4
|
+
data.tar.gz: c35f493949efff7a1066b118770f7cc6561161bd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 24bfa5207760d5b22596fb256ce96528091c1c8ca86081369580f4b203054e46b75dcb94fa977b7da60050c2556bf87673f7bdad34cf6a5bf3ab4d79b9578709
|
7
|
+
data.tar.gz: 2716208db8625414b0719ef79609c8efd8845eab75872939c039ce5e0ffb9f1e2f94fe0d81a6d74755a88e656a2a94e331e523ffe4aa9feb2e1aa3fe025261bd
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/History.txt
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2007 Ola Bini <ola.bini@gmail.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
JRuby/LDAP
|
2
|
+
-----------
|
3
|
+
|
4
|
+
This is an interface compatible port of Ruby/LDAP - to allow binary LDAP usage through JRuby. This implementation is pure Ruby, but uses the Java Integration features of JRuby to access the JNDI libraries and through these implement the correct functionality.
|
5
|
+
|
6
|
+
Many classes are missing right now, but the base functionality should be there.
|
7
|
+
|
8
|
+
|
9
|
+
Usage
|
10
|
+
-----
|
11
|
+
require 'rubygems'
|
12
|
+
require 'ldap'
|
13
|
+
|
14
|
+
And then use it like all tutorials of Ruby/LDAP show you.
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
task :default => [:test, :build]
|
5
|
+
|
6
|
+
desc "Run all tests"
|
7
|
+
task :test => [:test_all]
|
8
|
+
|
9
|
+
Rake::TestTask.new(:test_all) do |t|
|
10
|
+
t.test_files = FileList['test/**/test_*.rb']
|
11
|
+
t.libs << 'test'
|
12
|
+
t.libs.delete("lib") unless defined?(JRUBY_VERSION)
|
13
|
+
end
|
14
|
+
|
data/jruby-ldap.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "jruby-ldap/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "jruby-ldap-patched"
|
7
|
+
s.version = JRuby::LDAP::VERSION
|
8
|
+
s.authors = ["Ola Bini", "Peter Souter"]
|
9
|
+
s.email = ["ola.bini@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/petems/jruby-ldap-patched"
|
11
|
+
s.summary = "Port of Ruby/LDAP to JRuby, with patch for Puppetserver"
|
12
|
+
s.description = "Port of Ruby/LDAP to JRuby, with patch for Puppetserver"
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_development_dependency 'rake', '< 11.0'
|
20
|
+
end
|
data/lib/jruby-ldap.rb
ADDED
data/lib/ldap.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'java'
|
2
|
+
|
3
|
+
module LDAP
|
4
|
+
def self.err2string(err)
|
5
|
+
case err||0
|
6
|
+
when -1 then "Can't contact LDAP server"
|
7
|
+
when 0 then "Success"
|
8
|
+
when 1 then "Operations error"
|
9
|
+
when 2 then "Protocol error"
|
10
|
+
when 3 then "Time limit exceeded"
|
11
|
+
when 4 then "Size limit exceeded"
|
12
|
+
when 5 then "Compare False"
|
13
|
+
when 6 then "Compare True"
|
14
|
+
when 7 then "Authentication method not supported"
|
15
|
+
when 8 then "Strong(er) authentication required"
|
16
|
+
when 9 then "Partial results and referral received"
|
17
|
+
when 10 then "Referral"
|
18
|
+
when 11 then "Administrative limit exceeded"
|
19
|
+
when 12 then "Critical extension is unavailable"
|
20
|
+
when 13 then "Confidentiality required"
|
21
|
+
when 14 then "SASL bind in progress"
|
22
|
+
when 15 then "Unknown error"
|
23
|
+
when 16 then "No such attribute"
|
24
|
+
when 17 then "Undefined attribute type"
|
25
|
+
when 18 then "Inappropriate matching"
|
26
|
+
when 19 then "Constraint violation"
|
27
|
+
when 20 then "Type or value exists"
|
28
|
+
when 21 then "Invalid syntax"
|
29
|
+
when 32 then "No such object"
|
30
|
+
when 33 then "Alias problem"
|
31
|
+
when 34 then "Invalid DN syntax"
|
32
|
+
when 35 then "Entry is a leaf"
|
33
|
+
when 36 then "Alias dereferencing problem"
|
34
|
+
when 47 then "Proxy Authorization Failure"
|
35
|
+
when 48 then "Inappropriate authentication"
|
36
|
+
when 49 then "Invalid credentials"
|
37
|
+
when 50 then "Insufficient access"
|
38
|
+
when 51 then "Server is busy"
|
39
|
+
when 52 then "Server is unavailable"
|
40
|
+
when 53 then "Server is unwilling to perform"
|
41
|
+
when 54 then "Loop detected"
|
42
|
+
when 64 then "Naming violation"
|
43
|
+
when 65 then "Object class violation"
|
44
|
+
when 66 then "Operation not allowed on non-leaf"
|
45
|
+
when 67 then "Operation not allowed on RDN"
|
46
|
+
when 68 then "Already exists"
|
47
|
+
when 69 then "Cannot modify object class"
|
48
|
+
when 70 then "Results too large"
|
49
|
+
when 71 then "Operation affects multiple DSAs"
|
50
|
+
when 80 then "Internal (implementation specific) error"
|
51
|
+
else "Unknown error"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.load_configuration(attrs={})
|
56
|
+
env = nil
|
57
|
+
env = javax.naming.directory.InitialDirContext.new.environment rescue nil
|
58
|
+
default = {'java.naming.factory.initial' => 'com.sun.jndi.ldap.LdapCtxFactory'}
|
59
|
+
if env
|
60
|
+
env2 = default.dup
|
61
|
+
env.each do |k,v|
|
62
|
+
env2[k.to_s] = v.to_s
|
63
|
+
end
|
64
|
+
env = env2
|
65
|
+
else
|
66
|
+
env = default.dup
|
67
|
+
end
|
68
|
+
env.merge! attrs
|
69
|
+
@environment = env
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.configuration(attrs = { })
|
73
|
+
@environment.merge attrs
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
require 'ldap/constants'
|
78
|
+
require 'ldap/conn'
|
79
|
+
require 'ldap/entry'
|
80
|
+
require 'ldap/error'
|
81
|
+
require 'ldap/mod'
|
82
|
+
|
83
|
+
LDAP.load_configuration
|
data/lib/ldap/conn.rb
ADDED
@@ -0,0 +1,285 @@
|
|
1
|
+
module LDAP
|
2
|
+
module ConnImplementation
|
3
|
+
|
4
|
+
if RUBY_PLATFORM =~ /^java.*/i
|
5
|
+
class LDAP::Entry
|
6
|
+
def to_hash
|
7
|
+
h = {}
|
8
|
+
get_attributes.each { |a| h[a.to_sym] = self[a] }
|
9
|
+
h[:dn] = [dn]
|
10
|
+
h
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def controls(*args)
|
16
|
+
raise "NOT IMPLEMENTED"
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_option(*args)
|
20
|
+
raise "NOT IMPLEMENTED"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Modify the RDN of the entry with DN, +dn+, giving it the new RDN,
|
24
|
+
# +new_rdn+. If +delete_old_rdn+ is *true*, the old RDN value will be deleted
|
25
|
+
# from the entry.
|
26
|
+
def modrdn(dn, new_rdn, delete_old_rdn)
|
27
|
+
begin
|
28
|
+
if delete_old_rdn
|
29
|
+
@context.rename(dn, new_rdn)
|
30
|
+
else
|
31
|
+
obj = @context.lookup(dn)
|
32
|
+
@context.bind(new_rdn, obj)
|
33
|
+
end
|
34
|
+
@err = 0
|
35
|
+
rescue javax.naming.NameAlreadyBoundException => e
|
36
|
+
@err = 68
|
37
|
+
rescue javax.naming.InvalidNameException => e
|
38
|
+
@err = 34
|
39
|
+
rescue javax.naming.NoPermissionException => e
|
40
|
+
@err = 50
|
41
|
+
rescue javax.naming.directory.SchemaViolationException => e
|
42
|
+
@err = 65
|
43
|
+
rescue javax.naming.NamingException => e
|
44
|
+
@err = 21
|
45
|
+
rescue javax.naming.NoPermissionException => e
|
46
|
+
@err = 50
|
47
|
+
rescue javax.naming.NamingException => e
|
48
|
+
@err = -1
|
49
|
+
end
|
50
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e) if @err != 0
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
def perror(*args)
|
55
|
+
raise "NOT IMPLEMENTED"
|
56
|
+
end
|
57
|
+
|
58
|
+
def referrals(*args)
|
59
|
+
raise "NOT IMPLEMENTED"
|
60
|
+
end
|
61
|
+
|
62
|
+
def result2error(*args)
|
63
|
+
raise "NOT IMPLEMENTED"
|
64
|
+
end
|
65
|
+
|
66
|
+
def __jndi_context
|
67
|
+
@context
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialize(host='localhost', port=LDAP_PORT)
|
71
|
+
@host = host
|
72
|
+
@port = port
|
73
|
+
end
|
74
|
+
|
75
|
+
def err
|
76
|
+
@err || 0
|
77
|
+
end
|
78
|
+
|
79
|
+
def err2string(err)
|
80
|
+
LDAP.err2string(err)
|
81
|
+
end
|
82
|
+
|
83
|
+
def simple_bind(dn=nil, password=nil, &block)
|
84
|
+
bind(dn, password, LDAP_AUTH_SIMPLE, &block)
|
85
|
+
end
|
86
|
+
|
87
|
+
def bind(dn=nil, password=nil, method=LDAP_AUTH_SIMPLE)
|
88
|
+
raise LDAP::Error, "already bound" if bound?
|
89
|
+
|
90
|
+
url = @use_ssl ? "ldaps://#@host:#@port/" : "ldap://#@host:#@port/"
|
91
|
+
base_env = {javax.naming.Context::PROVIDER_URL => url}
|
92
|
+
base_env[javax.naming.Context::SECURITY_PRINCIPAL] = dn if dn
|
93
|
+
base_env[javax.naming.Context::SECURITY_CREDENTIALS] = password if password
|
94
|
+
|
95
|
+
@current_env = java.util.Hashtable.new(LDAP::configuration(base_env))
|
96
|
+
|
97
|
+
begin
|
98
|
+
@context = javax.naming.directory.InitialDirContext.new(@current_env)
|
99
|
+
@err = 0
|
100
|
+
rescue javax.naming.NoPermissionException => e
|
101
|
+
@err = 50
|
102
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
103
|
+
rescue javax.naming.NamingException => e
|
104
|
+
@err = -1
|
105
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
106
|
+
end
|
107
|
+
|
108
|
+
if !block_given?
|
109
|
+
return self
|
110
|
+
end
|
111
|
+
|
112
|
+
begin
|
113
|
+
yield self
|
114
|
+
|
115
|
+
return nil
|
116
|
+
ensure
|
117
|
+
unbind
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def set_option(opt, value)
|
122
|
+
@err = 0
|
123
|
+
end
|
124
|
+
|
125
|
+
def add(dn, attrs)
|
126
|
+
raise LDAP::InvalidDataError, "The LDAP handler has already unbound." unless bound?
|
127
|
+
|
128
|
+
attrs = LDAP::hash2mods(LDAP::LDAP_MOD_ADD, attrs) if attrs.is_a?(Hash)
|
129
|
+
|
130
|
+
begin
|
131
|
+
@context.create_subcontext(dn, LDAP::Mod.to_java_attributes(*attrs))
|
132
|
+
@err = 0
|
133
|
+
rescue javax.naming.NameNotFoundException => e
|
134
|
+
@err = 32
|
135
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
136
|
+
rescue javax.naming.InvalidNameException => e
|
137
|
+
@err = 34
|
138
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
139
|
+
rescue javax.naming.NoPermissionException => e
|
140
|
+
@err = 50
|
141
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
142
|
+
rescue javax.naming.directory.SchemaViolationException => e
|
143
|
+
@err = 65
|
144
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
145
|
+
rescue javax.naming.NamingException => e
|
146
|
+
@err = 21
|
147
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
148
|
+
end
|
149
|
+
self
|
150
|
+
end
|
151
|
+
|
152
|
+
def modify(dn, attrs)
|
153
|
+
raise LDAP::InvalidDataError, "The LDAP handler has already unbound." unless bound?
|
154
|
+
|
155
|
+
attrs = LDAP::hash2mods(LDAP::LDAP_MOD_REPLACE, attrs) if attrs.is_a?(Hash)
|
156
|
+
|
157
|
+
begin
|
158
|
+
@context.modify_attributes(dn, LDAP::Mod.to_java_modification_items(*attrs))
|
159
|
+
@err = 0
|
160
|
+
rescue javax.naming.NameNotFoundException => e
|
161
|
+
@err = 32
|
162
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
163
|
+
rescue javax.naming.InvalidNameException => e
|
164
|
+
@err = 34
|
165
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
166
|
+
rescue javax.naming.NoPermissionException => e
|
167
|
+
@err = 50
|
168
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
169
|
+
rescue javax.naming.directory.SchemaViolationException => e
|
170
|
+
@err = 65
|
171
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
172
|
+
rescue javax.naming.NamingException => e
|
173
|
+
@err = 21
|
174
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
175
|
+
end
|
176
|
+
|
177
|
+
self
|
178
|
+
end
|
179
|
+
|
180
|
+
def delete(dn)
|
181
|
+
raise LDAP::InvalidDataError, "The LDAP handler has already unbound." unless bound?
|
182
|
+
|
183
|
+
begin
|
184
|
+
@context.destroy_subcontext(dn)
|
185
|
+
@err = 0
|
186
|
+
rescue javax.naming.NameNotFoundException => e
|
187
|
+
@err = 32
|
188
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
189
|
+
rescue javax.naming.InvalidNameException => e
|
190
|
+
@err = 34
|
191
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
192
|
+
rescue javax.naming.NoPermissionException => e
|
193
|
+
@err = 50
|
194
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
195
|
+
rescue javax.naming.NamingException => e
|
196
|
+
@err = 21
|
197
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
198
|
+
end
|
199
|
+
self
|
200
|
+
end
|
201
|
+
|
202
|
+
def search(base_dn, scope, filter, attrs=nil, attrsonly=nil, sec=0, usec=0, s_attr=nil, s_proc=nil)
|
203
|
+
raise LDAP::InvalidDataError, "The LDAP handler has already unbound." unless bound?
|
204
|
+
|
205
|
+
controls = javax.naming.directory.SearchControls.new
|
206
|
+
controls.search_scope = scope
|
207
|
+
|
208
|
+
if attrs && !attrs.empty?
|
209
|
+
controls.returning_attributes = attrs.to_java(:string)
|
210
|
+
end
|
211
|
+
if attrsonly
|
212
|
+
controls.returning_obj_flag = true
|
213
|
+
end
|
214
|
+
|
215
|
+
if sec != 0 || usec != 0
|
216
|
+
controls.time_limit = usec/1000 + sec*1000
|
217
|
+
end
|
218
|
+
|
219
|
+
begin
|
220
|
+
@context.search(base_dn, filter, controls).each do |val|
|
221
|
+
yield LDAP::Entry.create_from_search_result(val)
|
222
|
+
end
|
223
|
+
|
224
|
+
@err = 0
|
225
|
+
rescue javax.naming.NameNotFoundException => e
|
226
|
+
@err = 32
|
227
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
228
|
+
rescue javax.naming.InvalidNameException => e
|
229
|
+
@err = 34
|
230
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
231
|
+
rescue javax.naming.NoPermissionException => e
|
232
|
+
@err = 50
|
233
|
+
raise LDAP::ResultError.wrap(LDAP::err2string(@err), e)
|
234
|
+
end
|
235
|
+
|
236
|
+
self
|
237
|
+
end
|
238
|
+
|
239
|
+
def search2(base_dn, scope, filter, attrs=nil, attrsonly=nil, sec=0, usec=0, s_attr=nil, s_proc=nil)
|
240
|
+
arr = []
|
241
|
+
search(base_dn, scope, filter, attrs, attrsonly, sec, usec, s_attr, s_proc) do |val|
|
242
|
+
arr << LDAP::entry2hash(val)
|
243
|
+
end
|
244
|
+
arr
|
245
|
+
end
|
246
|
+
|
247
|
+
def unbind
|
248
|
+
raise LDAP::InvalidDataError, "The LDAP handler has already unbound." unless bound?
|
249
|
+
@context.close
|
250
|
+
@err = 0
|
251
|
+
@context = nil
|
252
|
+
end
|
253
|
+
|
254
|
+
def bound?
|
255
|
+
!@context.nil?
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
|
260
|
+
class Conn
|
261
|
+
class << self
|
262
|
+
alias open new
|
263
|
+
end
|
264
|
+
|
265
|
+
def initialize(host='localhost', port=LDAP_PORT)
|
266
|
+
super
|
267
|
+
@use_ssl = false
|
268
|
+
end
|
269
|
+
|
270
|
+
include ConnImplementation
|
271
|
+
end
|
272
|
+
|
273
|
+
class SSLConn
|
274
|
+
class << self
|
275
|
+
alias open new
|
276
|
+
end
|
277
|
+
|
278
|
+
def initialize(host='localhost', port=LDAPS_PORT)
|
279
|
+
super
|
280
|
+
@use_ssl = true
|
281
|
+
end
|
282
|
+
|
283
|
+
include ConnImplementation
|
284
|
+
end
|
285
|
+
end
|