Skip to content

Commit 537dc5e

Browse files
author
Dave Sims
committed
Restarting referrals from #87
1 parent c3b2401 commit 537dc5e

File tree

3 files changed

+54
-4
lines changed

3 files changed

+54
-4
lines changed

lib/github/ldap.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'net/ldap'
22
require 'forwardable'
3+
require 'uri'
34

45
require 'github/ldap/filter'
56
require 'github/ldap/domain'
@@ -100,6 +101,9 @@ def initialize(options = {})
100101

101102
# enables instrumenting queries
102103
@instrumentation_service = options[:instrumentation_service]
104+
105+
# referral connection handle
106+
@referrals = {}
103107
end
104108

105109
# Public - Whether membership checks should recurse into nested groups when
@@ -187,7 +191,51 @@ def search(options, &block)
187191
result.concat Array(rs) unless rs == false
188192
end
189193
end
194+
if options[:return_referrals]
195+
ref_result = []
196+
result.delete_if do |entry|
197+
if entry.respond_to?('search_referrals')
198+
rs = search_referrals(entry[:search_referrals], options, &block)
199+
ref_result.concat Array(rs) unless rs == false
200+
true
201+
else
202+
false
203+
end
204+
end
205+
result.concat ref_result
206+
end
207+
return [] if result == false
208+
Array(result)
209+
end
210+
end
190211

212+
# Internal: Searches the referral LDAP servers
213+
#
214+
# referal_hosts: list of referral hosts uris
215+
# options: is a hash with the same options that Net::LDAP::Connection#search supports.
216+
# block: is an optional block to pass to the search.
217+
#
218+
# Returns an Array of Net::LDAP::Entry.
219+
def search_referrals(referral_uris, options, &block)
220+
instrument "search_referrals.github_ldap", options.dup do |payload|
221+
options.delete(:return_referrals)
222+
result = []
223+
referral_uris.each do |referral_url|
224+
unless @referrals.has_key? referral_url
225+
uri = URI(referral_url)
226+
@referrals[referral_url] = Net::LDAP.new({
227+
host: uri.host,
228+
port: uri.port,
229+
base: uri.path.sub(/^\//, ''),
230+
auth: @connection.instance_variable_get(:@auth),
231+
encryption: @connection.instance_variable_get(:@encryption),
232+
instrumentation_service: @connection.instance_variable_get(:@instrumentation_service)
233+
})
234+
end
235+
options.delete(:base)
236+
rs = @referrals[referral_url].search(options, &block)
237+
result.concat Array(rs) unless rs == false
238+
end
191239
return [] if result == false
192240
Array(result)
193241
end

lib/github/ldap/member_search/recursive.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ def find_groups_by_dn(dn)
123123
base: dn,
124124
scope: Net::LDAP::SearchScope_BaseObject,
125125
attributes: attrs,
126-
filter: ALL_GROUPS_FILTER
126+
filter: ALL_GROUPS_FILTER,
127+
return_referrals: true
127128
end
128129
private :find_groups_by_dn
129130

@@ -133,7 +134,7 @@ def find_groups_by_dn(dn)
133134
def entries_by_uid(members)
134135
filter = members.map { |uid| Net::LDAP::Filter.eq(ldap.uid, uid) }.reduce(:|)
135136
domains.each_with_object([]) do |domain, entries|
136-
entries.concat domain.search(filter: filter, attributes: attrs)
137+
entries.concat domain.search(filter: filter, attributes: attrs, return_referrals: true)
137138
end.compact
138139
end
139140
private :entries_by_uid

lib/github/ldap/membership_validators/recursive.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def perform(entry, depth_override = nil)
5151

5252
domains.each do |domain|
5353
# find groups entry is an immediate member of
54-
membership = domain.search(filter: member_filter(entry), attributes: ATTRS)
54+
membership = domain.search(filter: member_filter(entry), attributes: ATTRS, return_referrals: true)
5555

5656
# success if any of these groups match the restricted auth groups
5757
return true if membership.any? { |entry| group_dns.include?(entry.dn) }
@@ -62,7 +62,7 @@ def perform(entry, depth_override = nil)
6262
# recurse to at most `depth`
6363
(depth_override || depth).times do |n|
6464
# find groups whose members include membership groups
65-
membership = domain.search(filter: membership_filter(membership), attributes: ATTRS)
65+
membership = domain.search(filter: membership_filter(membership), attributes: ATTRS, return_referrals: true)
6666

6767
# success if any of these groups match the restricted auth groups
6868
return true if membership.any? { |entry| group_dns.include?(entry.dn) }
@@ -115,3 +115,4 @@ def group_dns
115115
end
116116
end
117117
end
118+

0 commit comments

Comments
 (0)