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