Browse Source

server2

main
pvincent 2 weeks ago
parent
commit
00e4cadda6
  1. 22
      examples/ldapdb.yaml
  2. 74
      examples/server1.rb
  3. 93
      examples/server2.rb

22
examples/ldapdb.yaml

@ -1,17 +1,21 @@
--- ---
dc=example,dc=com:
dc=zourit,dc=re:
cn: cn:
- Top object - Top object
cn=fred flintstone,dc=example,dc=com:
cn=pvincent,dc=zourit,dc=re:
cn: cn:
- Fred Flintstone
- pvincent
sn: sn:
- Flintstone
- P.Vincent
mail: mail:
- fred@bedrock.org
- fred.flintstone@bedrock.org
cn=wilma flintstone,dc=example,dc=com:
- pvincent@zourit.re
dc=pvincent,dc=re:
cn: cn:
- Wilma Flintstone
- Top object
cn=admin,dc=pvincent,dc=re:
cn:
- admin
sn:
- Vincentdmin
mail: mail:
- wilma@bedrock.org
- admin@pvincent.re

74
examples/server.rb → examples/server1.rb

@ -1,4 +1,4 @@
#!/usr/local/bin/ruby -w
#!/usr/bin/env ruby
# This is a modified version of rbslapd1.rb which uses a Router instead of # This is a modified version of rbslapd1.rb which uses a Router instead of
# subclassing the LDAP::Server::Operation class. # subclassing the LDAP::Server::Operation class.
@ -15,7 +15,45 @@ require 'ldap/server/router'
$logger = Logger.new($stderr) $logger = Logger.new($stderr)
class HashOperation < LDAP::Server::Operation
def initialize
super
@hash = YAML.load_from_file('ldapdbp.yaml') # an object reference to our directory data
end
def search(basedn, scope, deref, filter)
basedn = basedn.downcase
case scope
when LDAP::Server::BaseObject
# client asked for single object by DN
obj = @hash[basedn]
raise LDAP::ResultError::NoSuchObject unless obj
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?
send_SearchResultEntry(dn, av)
end
else
raise LDAP::ResultError::UnwillingToPerform, 'OneLevel not implemented'
end
end
end
class LDAPController class LDAPController
def initialize
@directory = {}
File.open('ldapdb.yaml') { |f| @directory = YAML.load(f.read) }
end
def self.bind(request, version, dn, password, params) def self.bind(request, version, dn, password, params)
$logger.debug 'Catchall bind request' $logger.debug 'Catchall bind request'
raise LDAP::ResultError::UnwillingToPerform, 'Invalid bind DN' raise LDAP::ResultError::UnwillingToPerform, 'Invalid bind DN'
@ -35,13 +73,34 @@ class LDAPController
$logger.info "Authenticated email=#{user}@#{domain}.#{tld} with password=<ANY>" $logger.info "Authenticated email=#{user}@#{domain}.#{tld} with password=<ANY>"
end end
def self.search(request, baseObject, scope, deref, filter, params)
$logger.info "Catchall search request for #{baseObject}"
raise LDAP::ResultError::UnwillingToPerform, 'Invalid search DN'
end
def self.searchUsers(request, baseObject, scope, deref, filter, params) def self.searchUsers(request, baseObject, scope, deref, filter, params)
$logger.info 'Search users' $logger.info 'Search users'
domain = params[:domain]
tld = params[:tld]
basedn = "#{domain}.#{tld}"
operation = HashOperation.new
case scope
when LDAP::Server::BaseObject
# client asked for single object by DN
obj = directory
raise LDAP::ResultError::NoSuchObject unless obj
operation.send_SearchResultEntry(basedn, obj) if LDAP::Server::Filter.run(filter, obj)
when LDAP::Server::WholeSubtree
directory.each do |dn, av|
next unless dn.index(basedn, -basedn.length) # under basedn?
next unless LDAP::Server::Filter.run(filter, av) # attribute filter?
operation.send_SearchResultEntry(dn, av)
end
else
raise LDAP::ResultError::UnwillingToPerform, 'OneLevel not implemented'
end
end end
end end
@ -53,7 +112,8 @@ router = LDAP::Server::Router.new($logger) do
# Bind a route using variables. A hash with the variables will be passed # Bind a route using variables. A hash with the variables will be passed
# to your function as last argument. # to your function as last argument.
# bind 'uid=:uid,ou=Users,dc=mydomain,dc=com' => 'LDAPController#bindUser' # bind 'uid=:uid,ou=Users,dc=mydomain,dc=com' => 'LDAPController#bindUser'
bind 'uid=:uid,ou=Users,dc=:domain,dc=:tld' => 'LDAPController#bindUser'
bind 'uid=:uid,dc=:domain,dc=:tld' => 'LDAPController#bindUser'
search 'dc=:domain,dc=:tld' => 'LDAPController#searchUsers'
# search nil => 'LDAPController#search' # search nil => 'LDAPController#search'
# search 'ou=Users,dc=mydomain,dc=com' => 'LDAPController#searchUsers' # search 'ou=Users,dc=mydomain,dc=com' => 'LDAPController#searchUsers'

93
examples/server2.rb

@ -0,0 +1,93 @@
#!/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}")
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
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?
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
Loading…
Cancel
Save