-
Notifications
You must be signed in to change notification settings - Fork 26
Multi Domain query #89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -100,6 +100,9 @@ def initialize(options = {}) | |
|
|
||
| # enables instrumenting queries | ||
| @instrumentation_service = options[:instrumentation_service] | ||
|
|
||
| # active directory forest | ||
| @forest = get_domain_forest(options[:search_forest]) | ||
| end | ||
|
|
||
| # Public - Whether membership checks should recurse into nested groups when | ||
|
|
@@ -180,10 +183,10 @@ def search(options, &block) | |
| instrument "search.github_ldap", options.dup do |payload| | ||
| result = | ||
| if options[:base] | ||
| @connection.search(options, &block) | ||
| forest_search(options, &block) | ||
| else | ||
| search_domains.each_with_object([]) do |base, result| | ||
| rs = @connection.search(options.merge(:base => base), &block) | ||
| rs = forest_search(options.merge(:base => base), &block) | ||
| result.concat Array(rs) unless rs == false | ||
| end | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Never seen the tree ( |
||
| end | ||
|
|
@@ -193,6 +196,26 @@ def search(options, &block) | |
| end | ||
| end | ||
|
|
||
| # Internal: Search within a ldap forest | ||
| # | ||
| # Returns an Array of Net::LDAP::Entry. | ||
| def forest_search(options, &block) | ||
| instrument "forest_search.github_ldap" do |payload| | ||
| result = | ||
| if @forest.empty? | ||
| @connection.search(options, &block) | ||
| else | ||
| @forest.each_with_object([]) do |(rootdn, server), res| | ||
| if options[:base].end_with?(rootdn) | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Requires to use
|
||
| rs = server.search(options, &block) | ||
| res.concat Array(rs) unless rs == false | ||
| end | ||
| end | ||
| end | ||
| return result | ||
| end | ||
| end | ||
|
|
||
| # Internal: Searches the host LDAP server's Root DSE for capabilities and | ||
| # extensions. | ||
| # | ||
|
|
@@ -201,7 +224,8 @@ def capabilities | |
| @capabilities ||= | ||
| instrument "capabilities.github_ldap" do |payload| | ||
| begin | ||
| @connection.search_root_dse | ||
| rs = @connection.search(:ignore_server_caps => true, :base => "", :scope => Net::LDAP::SearchScope_BaseObject) | ||
| (rs and rs.first) | ||
| rescue Net::LDAP::LdapError => error | ||
| payload[:error] = error | ||
| # stubbed result | ||
|
|
@@ -307,6 +331,37 @@ def configure_member_search_strategy(strategy = nil) | |
| end | ||
| end | ||
|
|
||
| # Internal: Queries configuration for available domains | ||
| # | ||
| # Membership of local or global groups need to be evaluated by contacting referral Donmain Controllers | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| # | ||
| # Returns all Domain Controllers within the forest | ||
| def get_domain_forest(search_forest) | ||
| instrument "get_domain_forest.github_ldap" do |payload| | ||
|
|
||
| # if we are talking to an active directory | ||
| if search_forest and active_directory_capability? and capabilities[:configurationnamingcontext].any? | ||
| domains = @connection.search( | ||
| base: capabilities[:configurationnamingcontext].first, | ||
| search_referrals: true, | ||
| filter: Net::LDAP::Filter.eq("nETBIOSName", "*") | ||
| ) | ||
| return domains.each_with_object({}) do |server, result| | ||
| if server[:ncname].any? and server[:dnsroot].any? | ||
| result[server[:ncname].first] = Net::LDAP.new({ | ||
| host: server[:dnsroot].first, | ||
| port: @connection.instance_variable_get(:@encryption)? 636 : 389, | ||
| auth: @connection.instance_variable_get(:@auth), | ||
| encryption: @connection.instance_variable_get(:@encryption), | ||
| instrumentation_service: @connection.instance_variable_get(:@instrumentation_service) | ||
| }) | ||
| end | ||
| end | ||
| end | ||
| return {} | ||
| end | ||
| end | ||
|
|
||
| # Internal: Detect whether the LDAP host is an ActiveDirectory server. | ||
| # | ||
| # See: http://msdn.microsoft.com/en-us/library/cc223359.aspx. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requries
options[:search_forest]to be provided from the outsideThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GitHub Enterprise instantiates a global strategy. As such, we need to provide an interface to refresh the list of domain controllers so that a configuration update does not require a restart of the appliance.