server2
This commit is contained in:
+13
-9
@@ -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
|
- pvincent@zourit.re
|
||||||
- fred.flintstone@bedrock.org
|
dc=pvincent,dc=re:
|
||||||
cn=wilma flintstone,dc=example,dc=com:
|
|
||||||
cn:
|
cn:
|
||||||
- Wilma Flintstone
|
- Top object
|
||||||
|
cn=admin,dc=pvincent,dc=re:
|
||||||
|
cn:
|
||||||
|
- admin
|
||||||
|
sn:
|
||||||
|
- Vincentdmin
|
||||||
mail:
|
mail:
|
||||||
- wilma@bedrock.org
|
- admin@pvincent.re
|
||||||
|
|||||||
Regular → Executable
+67
-7
@@ -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'
|
||||||
Executable
+93
@@ -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
|
||||||
Reference in New Issue
Block a user