Open HynekPetrak opened 4 years ago
Interesting. We'll have to see if we can reproduce this with an OpenLDAP container.
I was able to get this response doing the following
# Run an OpenLDAP container in a separate terminal
scripts/ldap-docker
# Make a successful anonymous bind and search
ldapsearch -x -H ldap://localhost -b '' -s base namingContexts
# Change the configuration to disallow anonymous bind
ldapmodify -x -H ldap://localhost -D 'cn=admin,cn=config' -w 'config' <<+
dn: cn=config
changetype: modify
replace: olcDisallows
olcDisallows: bind_anon
+
# Make an unsuccessful bind and search
ldapsearch -x -H ldap://localhost -b '' -s base namingContexts
# ldap_bind: Inappropriate authentication (48)
# additional info: anonymous bind disallowed
We see that when the anonymous bind fails, we do not get a successful search result back using ldapsearch
.
This reproduces the issue as well
require_relative 'lib/net-ldap'
@ldap = Net::LDAP.new host: 'localhost',
port: 389,
auth: { method: :anonymous }
@ldap_config = Net::LDAP.new host: 'localhost',
port: 389,
auth: {
method: :simple,
username: 'cn=admin,cn=config',
password: 'config'
}
def print_naming_contexts
puts "\nSearching anonymously"
puts @ldap.search(base: '', scope: Net::LDAP::SearchScope_BaseObject, attributes: %w[namingContexts])
.map(&:to_ldif)
puts @ldap.get_operation_result.message
end
puts "\nEnabling anonymous bind"
@ldap_config.modify dn: 'cn=config',
operations: [
[:delete, 'olcDisallows']
]
puts @ldap_config.get_operation_result.message
print_naming_contexts
puts "\nDisabling anonymous bind"
@ldap_config.modify dn: 'cn=config',
operations: [
[:replace, 'olcDisallows', ['bind_anon']]
]
puts @ldap_config.get_operation_result.message
print_naming_contexts
I'm thinking we'll want to indicate somehow that the bind failed but the search succeeded. Perhaps print a warning?
# Yields an open connection if there is one, otherwise establishes a new
# connection, binds, and yields it. If binding fails, it will return the
# result from that, and :use_connection: will not yield at all. If not
# the return value is whatever is returned from the block.
def use_connection(args)
if @open_connection
yield @open_connection
else
begin
conn = new_connection
auth = args[:auth] || @auth
result = conn.bind(auth)
unless [Net::LDAP::ResultCodeSuccess,
Net::LDAP::ResultCodeInappropriateAuthentication].include?(result.result_code)
return result
end
if result.result_code == Net::LDAP::ResultCodeInappropriateAuthentication
warn "Inappropriate authentication occurred with #{auth[:method]} auth."
end
yield conn
ensure
conn.close if conn
end
end
end
Ldapsearch perhaps does not print a search result when an anonymous bind fails, however the server returns the result. Tested when you run the search within a #open |ldap| block
We should also test this with another LDAP server such as OpenDJ to see what would happen there.
In situation when OpenLDAP is configured with "disallow bind_anon" in slapd.conf, the bind operation will return "LDAP_INAPPROPRIATE_AUTH - anonymous bind disallowed". According to https://www.openldap.org/doc/admin23/security.html#Authentication%20Methods a anonymous bind is not fatal for an LDAP server and server will still respond to search or other operations, according to ACLs. Quoting: "Note that disabling the anonymous bind mechanism does not prevent anonymous access to the directory."
Can you remove the line
return result unless result.result_code == Net::LDAP::ResultCodeSuccess
fromuse_connection
method? https://github.com/ruby-ldap/ruby-net-ldap/blob/master/lib/net/ldap.rb#L1310To be able to perform search and other operation even after bind has failed?