2014-03-10 08:48:08 -04:00
|
|
|
module Gitlab
|
|
|
|
module LDAP
|
|
|
|
class Adapter
|
2014-10-13 11:24:05 -04:00
|
|
|
attr_reader :provider, :ldap
|
2014-03-10 08:48:08 -04:00
|
|
|
|
2014-10-13 11:24:05 -04:00
|
|
|
def self.open(provider, &block)
|
|
|
|
Net::LDAP.open(config(provider).adapter_options) do |ldap|
|
|
|
|
block.call(self.new(provider, ldap))
|
2014-03-14 03:53:46 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-10-13 11:24:05 -04:00
|
|
|
def self.config(provider)
|
|
|
|
Gitlab::LDAP::Config.new(provider)
|
2014-03-14 03:53:46 -04:00
|
|
|
end
|
|
|
|
|
2016-08-05 22:03:01 -04:00
|
|
|
def initialize(provider, ldap = nil)
|
2014-10-13 11:24:05 -04:00
|
|
|
@provider = provider
|
|
|
|
@ldap = ldap || Net::LDAP.new(config.adapter_options)
|
2014-03-14 03:53:46 -04:00
|
|
|
end
|
|
|
|
|
2014-10-13 11:24:05 -04:00
|
|
|
def config
|
|
|
|
Gitlab::LDAP::Config.new(provider)
|
2014-03-10 08:48:08 -04:00
|
|
|
end
|
|
|
|
|
2014-10-21 11:26:40 -04:00
|
|
|
def users(field, value, limit = nil)
|
2016-09-02 06:52:13 -04:00
|
|
|
options = user_options(field, value, limit)
|
2014-10-21 11:26:40 -04:00
|
|
|
|
2014-05-14 12:10:43 -04:00
|
|
|
entries = ldap_search(options).select do |entry|
|
2014-03-10 08:48:08 -04:00
|
|
|
entry.respond_to? config.uid
|
|
|
|
end
|
|
|
|
|
|
|
|
entries.map do |entry|
|
2014-10-13 11:24:05 -04:00
|
|
|
Gitlab::LDAP::Person.new(entry, provider)
|
2014-03-10 08:48:08 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def user(*args)
|
|
|
|
users(*args).first
|
|
|
|
end
|
|
|
|
|
2014-05-14 12:11:14 -04:00
|
|
|
def dn_matches_filter?(dn, filter)
|
2015-02-03 00:15:44 -05:00
|
|
|
ldap_search(base: dn,
|
|
|
|
filter: filter,
|
|
|
|
scope: Net::LDAP::SearchScope_BaseObject,
|
|
|
|
attributes: %w{dn}).any?
|
2014-05-14 12:11:14 -04:00
|
|
|
end
|
|
|
|
|
2014-05-14 12:10:43 -04:00
|
|
|
def ldap_search(*args)
|
2015-12-31 14:22:51 -05:00
|
|
|
# Net::LDAP's `time` argument doesn't work. Use Ruby `Timeout` instead.
|
|
|
|
Timeout.timeout(config.timeout) do
|
|
|
|
results = ldap.search(*args)
|
2014-05-14 12:10:43 -04:00
|
|
|
|
2015-12-31 14:22:51 -05:00
|
|
|
if results.nil?
|
|
|
|
response = ldap.get_operation_result
|
2014-05-14 12:10:43 -04:00
|
|
|
|
2015-12-31 14:22:51 -05:00
|
|
|
unless response.code.zero?
|
|
|
|
Rails.logger.warn("LDAP search error: #{response.message}")
|
|
|
|
end
|
2014-05-14 12:10:43 -04:00
|
|
|
|
2015-12-31 14:22:51 -05:00
|
|
|
[]
|
|
|
|
else
|
|
|
|
results
|
|
|
|
end
|
2014-05-14 12:10:43 -04:00
|
|
|
end
|
2016-08-30 07:21:33 -04:00
|
|
|
rescue Net::LDAP::Error => error
|
|
|
|
Rails.logger.warn("LDAP search raised exception #{error.class}: #{error.message}")
|
|
|
|
[]
|
2015-12-31 14:22:51 -05:00
|
|
|
rescue Timeout::Error
|
|
|
|
Rails.logger.warn("LDAP search timed out after #{config.timeout} seconds")
|
|
|
|
[]
|
2014-05-14 12:10:43 -04:00
|
|
|
end
|
2016-09-02 06:52:13 -04:00
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def user_options(field, value, limit)
|
2016-09-15 23:46:22 -04:00
|
|
|
options = { attributes: user_attributes }
|
2016-09-02 06:52:13 -04:00
|
|
|
options[:size] = limit if limit
|
|
|
|
|
|
|
|
if field.to_sym == :dn
|
|
|
|
options[:base] = value
|
|
|
|
options[:scope] = Net::LDAP::SearchScope_BaseObject
|
|
|
|
options[:filter] = user_filter
|
|
|
|
else
|
|
|
|
options[:base] = config.base
|
|
|
|
options[:filter] = user_filter(Net::LDAP::Filter.eq(field, value))
|
|
|
|
end
|
|
|
|
|
|
|
|
options
|
|
|
|
end
|
|
|
|
|
|
|
|
def user_filter(filter = nil)
|
|
|
|
if config.user_filter.present?
|
|
|
|
user_filter = Net::LDAP::Filter.construct(config.user_filter)
|
|
|
|
end
|
|
|
|
|
|
|
|
if user_filter && filter
|
|
|
|
Net::LDAP::Filter.join(filter, user_filter)
|
|
|
|
elsif user_filter
|
|
|
|
user_filter
|
|
|
|
else
|
|
|
|
filter
|
|
|
|
end
|
|
|
|
end
|
2016-09-15 23:46:22 -04:00
|
|
|
|
|
|
|
def user_attributes
|
|
|
|
%W(#{config.uid} cn mail dn)
|
|
|
|
end
|
2014-03-10 08:48:08 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|