You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.8 KiB

#!/usr/bin/env ruby
$:.unshift('lib')
$debug = true
require 'ldap/server'
$logger = Logger.new($stderr)
# We subclass the Operation class, overriding the methods to do what we need
class HashOperation < LDAP::Server::Operation
def initialize(connection, messageID, hash)
super(connection, messageID)
@hash = hash # an object reference to our directory data
end
# ici, c'est bizarre
# systèmatiquement appelé (SEARCH ou AUTH)
# du coup, je retourne super si pas de dn => SEARCH normal sans authentication
# sinon ça passe aussi !!!
def do_bind(protocolOp, controls) # :nodoc:
dn = protocolOp.value[1].value
dn = nil if dn == ''
return super if dn.nil?
version = protocolOp.value[0].value
authentication = protocolOp.value[2]
password = authentication.value
$logger.info("AUTHENTICATION ..version=#{version}, dn=#{dn}, password=#{password}")
super
end
# def simple_bind(version, dn, password)
# super.simple_bind(version, dn, password)
# $logger.info("SIMPLE BIND...version=#{version}, dn=#{dn}")
#
# raise LDAP::ResultError::ProtocolError, 'version 3 only' if version != 3
# raise LDAP::ResultError::InvalidCredentials, 'Invalid credentials' if password.nil? || password == ''
#
# $logger.info('authentication SUCCESS')
# end
#
def search(basedn, scope, deref, filter)
$logger.info("SEARCHING...basedn=#{basedn}, scope=#{scope}, deref=#{deref}, filter=#{filter}")
basedn = basedn.downcase
result = nil
case scope
when LDAP::Server::BaseObject
# client asked for single object by DN
obj = @hash[basedn]
raise LDAP::ResultError::NoSuchObject unless obj
$logger.info('BaseObject')
result = send_SearchResultEntry(basedn, obj) if LDAP::Server::Filter.run(filter, obj)
when LDAP::Server::WholeSubtree
@hash.each do |dn, av|
next unless dn.index(basedn, -basedn.length) # under basedn?
next unless LDAP::Server::Filter.run(filter, av) # attribute filter?
$logger.info('WholeSubtree')
result = send_SearchResultEntry(dn, av)
end
else
raise LDAP::ResultError::UnwillingToPerform, 'OneLevel not implemented'
end
$logger.info "result=#{result}"
# result
end
end
# This is the shared object which carries our actual directory entries.
# It's just a hash of {dn=>entry}, where each entry is {attr=>[val,val,...]}
directory = {}
require 'yaml'
File.open('examples/ldapdb.yaml') { |f| directory = YAML.load(f.read) }
$logger.info("DIRECTORY=#{directory}")
# Listen for incoming LDAP connections. For each one, create a Connection
# object, which will invoke a HashOperation object for each request.
s = LDAP::Server.new(
port: 1389,
nodelay: true,
listen: 10,
operation_class: HashOperation,
operation_args: [directory]
)
$logger.info('server2 RUNNING...')
s.run_tcpserver
s.join