#!/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 valid = password == 'toto' $logger.info("AUTHENTICATION ..version=#{version}, dn=#{dn}, valid=#{valid}") send_BindResponse(valid ? 0 : 1) end def search(basedn, scope, deref, filter) $logger.info("SEARCHING...basedn=#{basedn}, scope=#{scope}, deref=#{deref}, filter=#{filter}") basedn = basedn.downcase 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') 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 av=#{av}") send_SearchResultEntry(dn, av) end else raise LDAP::ResultError::UnwillingToPerform, 'OneLevel not implemented' end 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