| Class | ActiveLdap::Adapter::NetLdap |
| In: |
lib/active_ldap/adapter/net_ldap.rb
|
| Parent: | Base |
| METHOD | = | { :ssl => :simple_tls, :tls => :start_tls, :plain => nil, } |
| CHARS | = | ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a |
# File lib/active_ldap/adapter/net_ldap.rb, line 111
111: def add(dn, entries, options={})
112: super do |dn, entries|
113: attributes = {}
114: entries.each do |type, key, attrs|
115: attrs.each do |name, values|
116: attributes[name] = values
117: end
118: end
119: execute(:add, :dn => dn, :attributes => attributes)
120: end
121: end
# File lib/active_ldap/adapter/net_ldap.rb, line 43
43: def bind(options={})
44: @bound = false
45: begin
46: super
47: rescue Net::LDAP::LdapError
48: raise AuthenticationError, $!.message
49: end
50: end
# File lib/active_ldap/adapter/net_ldap.rb, line 52
52: def bind_as_anonymous(options={})
53: super do
54: @bound = false
55: execute(:bind, :method => :anonymous)
56: @bound = true
57: end
58: end
# File lib/active_ldap/adapter/net_ldap.rb, line 60
60: def bound?
61: connecting? and @bound
62: end
# File lib/active_ldap/adapter/net_ldap.rb, line 23
23: def connect(options={})
24: @bound = false
25: super do |host, port, method|
26: config = {
27: :host => host,
28: :port => port,
29: }
30: config[:encryption] = {:method => method} if method
31: begin
32: Net::LDAP::Connection.new(config)
33: rescue Net::LDAP::LdapError
34: raise ConnectionError, $!.message
35: end
36: end
37: end
# File lib/active_ldap/adapter/net_ldap.rb, line 105
105: def delete(targets, options={})
106: super do |target|
107: execute(:delete, :dn => target)
108: end
109: end
# File lib/active_ldap/adapter/net_ldap.rb, line 91
91: def load(ldifs, options={})
92: super do |ldif|
93: entry = Net::LDAP::Entry.from_single_ldif_string(ldif)
94: attributes = {}
95: entry.each do |name, values|
96: attributes[name] = values
97: end
98: attributes.delete(:dn)
99: execute(:add,
100: :dn => entry.dn,
101: :attributes => attributes)
102: end
103: end
# File lib/active_ldap/adapter/net_ldap.rb, line 123
123: def modify(dn, entries, options={})
124: super do |dn, entries|
125: execute(:modify,
126: :dn => dn,
127: :operations => parse_entries(entries))
128: end
129: end
# File lib/active_ldap/adapter/net_ldap.rb, line 64
64: def search(options={}, &block)
65: super(options) do |base, scope, filter, attrs, limit, callback|
66: args = {
67: :base => base,
68: :scope => scope,
69: :filter => filter,
70: :attributes => attrs,
71: :size => limit,
72: }
73: execute(:search, args) do |entry|
74: attributes = {}
75: entry.original_attribute_names.each do |name|
76: attributes[name] = entry[name]
77: end
78: callback.call([entry.dn, attributes], block)
79: end
80: end
81: end
# File lib/active_ldap/adapter/net_ldap.rb, line 83
83: def to_ldif(dn, attributes)
84: entry = Net::LDAP::Entry.new(dn.dup)
85: attributes.each do |key, values|
86: entry[key] = values.flatten
87: end
88: entry.to_ldif
89: end
# File lib/active_ldap/adapter/net_ldap.rb, line 39
39: def unbind(options={})
40: @bound = false
41: end
# File lib/active_ldap/adapter/net_ldap.rb, line 155
155: def ensure_method(method)
156: method ||= "plain"
157: normalized_method = method.to_s.downcase.to_sym
158: return METHOD[normalized_method] if METHOD.has_key?(normalized_method)
159:
160: available_methods = METHOD.keys.collect {|m| m.inspect}.join(", ")
161: format = _("%s is not one of the available connect methods: %s")
162: raise ConfigurationError, format % [method.inspect, available_methods]
163: end
# File lib/active_ldap/adapter/net_ldap.rb, line 282
282: def ensure_mod_type(type)
283: case type
284: when :replace, :add
285: type
286: else
287: raise ArgumentError, _("unknown type: %s") % type
288: end
289: end
# File lib/active_ldap/adapter/net_ldap.rb, line 165
165: def ensure_scope(scope)
166: scope_map = {
167: :base => Net::LDAP::SearchScope_BaseObject,
168: :sub => Net::LDAP::SearchScope_WholeSubtree,
169: :one => Net::LDAP::SearchScope_SingleLevel,
170: }
171: value = scope_map[scope || :sub]
172: if value.nil?
173: available_scopes = scope_map.keys.inspect
174: format = _("%s is not one of the available LDAP scope: %s")
175: raise ArgumentError, format % [scope.inspect, available_scopes]
176: end
177: value
178: end
# File lib/active_ldap/adapter/net_ldap.rb, line 132
132: def execute(method, *args, &block)
133: result = @connection.send(method, *args, &block)
134: message = nil
135: if result.is_a?(Hash)
136: message = result[:errorMessage]
137: result = result[:resultCode]
138: end
139: unless result.zero?
140: klass = LdapError::ERRORS[result]
141: klass ||= LdapError
142: raise klass,
143: [Net::LDAP.result2string(result), message].compact.join(": ")
144: end
145: end
# File lib/active_ldap/adapter/net_ldap.rb, line 250
250: def generate_client_nonce(size=32)
251: nonce = ""
252: size.times do |i|
253: nonce << CHARS[rand(CHARS.size)]
254: end
255: nonce
256: end
# File lib/active_ldap/adapter/net_ldap.rb, line 271
271: def parse_entries(entries)
272: result = []
273: entries.each do |type, key, attributes|
274: mod_type = ensure_mod_type(type)
275: attributes.each do |name, values|
276: result << [mod_type, name, values]
277: end
278: end
279: result
280: end
# File lib/active_ldap/adapter/net_ldap.rb, line 241
241: def parse_sasl_digest_md5_credential(cred)
242: params = {}
243: cred.scan(/(\w+)=(\"?)(.+?)\2(?:,|$)/) do |name, sep, value|
244: params[name] = value
245: end
246: params
247: end
# File lib/active_ldap/adapter/net_ldap.rb, line 147
147: def root_dse(attrs, options={})
148: search(:base => "",
149: :scope => :base,
150: :attributes => attrs).collect do |dn, attributes|
151: attributes
152: end
153: end
# File lib/active_ldap/adapter/net_ldap.rb, line 180
180: def sasl_bind(bind_dn, options={})
181: super do |bind_dn, mechanism, quiet|
182: normalized_mechanism = mechanism.downcase.gsub(/-/, '_')
183: sasl_bind_setup = "sasl_bind_setup_#{normalized_mechanism}"
184: next unless respond_to?(sasl_bind_setup, true)
185: initial_credential, challenge_response =
186: send(sasl_bind_setup, bind_dn, options)
187: args = {
188: :method => :sasl,
189: :initial_credential => initial_credential,
190: :mechanism => mechanism,
191: :challenge_response => challenge_response,
192: }
193: @bound = false
194: execute(:bind, args)
195: @bound = true
196: end
197: end
# File lib/active_ldap/adapter/net_ldap.rb, line 199
199: def sasl_bind_setup_digest_md5(bind_dn, options)
200: initial_credential = ""
201: nonce_count = 1
202: challenge_response = Proc.new do |cred|
203: params = parse_sasl_digest_md5_credential(cred)
204: qops = params["qop"].split(/,/)
205: unless qops.include?("auth")
206: raise ActiveLdap::AuthenticationError,
207: _("unsupported qops: %s") % qops.inspect
208: end
209: qop = "auth"
210: server = @connection.instance_variable_get("@conn").addr[2]
211: realm = params['realm']
212: uri = "ldap/#{server}"
213: nc = "%08x" % nonce_count
214: nonce = params["nonce"]
215: cnonce = generate_client_nonce
216: requests = {
217: :username => bind_dn.inspect,
218: :realm => realm.inspect,
219: :nonce => nonce.inspect,
220: :cnonce => cnonce.inspect,
221: :nc => nc,
222: :qop => qop,
223: :maxbuf => "65536",
224: "digest-uri" => uri.inspect,
225: }
226: a1 = "#{bind_dn}:#{realm}:#{password(cred, options)}"
227: a1 = "#{Digest::MD5.digest(a1)}:#{nonce}:#{cnonce}"
228: ha1 = Digest::MD5.hexdigest(a1)
229: a2 = "AUTHENTICATE:#{uri}"
230: ha2 = Digest::MD5.hexdigest(a2)
231: response = "#{ha1}:#{nonce}:#{nc}:#{cnonce}:#{qop}:#{ha2}"
232: requests["response"] = Digest::MD5.hexdigest(response)
233: nonce_count += 1
234: requests.collect do |key, value|
235: "#{key}=#{value}"
236: end.join(",")
237: end
238: [initial_credential, challenge_response]
239: end
# File lib/active_ldap/adapter/net_ldap.rb, line 258
258: def simple_bind(bind_dn, options={})
259: super do |bind_dn, passwd|
260: args = {
261: :method => :simple,
262: :username => bind_dn,
263: :password => passwd,
264: }
265: @bound = false
266: execute(:bind, args)
267: @bound = true
268: end
269: end