From a4581ce8d930142c3862eb8f16d1a01c64d03a40 Mon Sep 17 00:00:00 2001 From: pvincent Date: Tue, 9 Jun 2026 07:19:42 +0000 Subject: [PATCH] server --- examples/client.rb | 23 +++++++++-- examples/rbslapd4.rb | 2 +- examples/server.rb | 93 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 5 deletions(-) mode change 100644 => 100755 examples/client.rb create mode 100644 examples/server.rb diff --git a/examples/client.rb b/examples/client.rb old mode 100644 new mode 100755 index cb69c64..05d5a80 --- a/examples/client.rb +++ b/examples/client.rb @@ -1,12 +1,27 @@ +#!/usr/bin/env ruby + require 'simple_ldap_authenticator' -DOMAIN = 'artcode' -TLD = 're' +raise 'Error: 2 arguments required => email + password' if ARGV.length != 2 + +email = ARGV.shift +password = ARGV.shift + +# puts "email=#{email}" +user = email.split('@').first +fqdn = email.split('@')[1] +fqdn_items = fqdn.split('.') +tld = fqdn_items.last +domain = fqdn_items[0..-2].join('.') +# puts "user=#{user}" +# puts "domain=#{domain}" +# puts "tld=#{tld}" +# SimpleLdapAuthenticator.servers = ['127.0.0.1'] SimpleLdapAuthenticator.port = 1389 SimpleLdapAuthenticator.use_ssl = false # SimpleLdapAuthenticator.login_format = '%s@mydomain.com' -SimpleLdapAuthenticator.login_format = "uid=%s,ou=Users,dc=#{DOMAIN},dc=#{TLD}" +SimpleLdapAuthenticator.login_format = "uid=%s,ou=Users,dc=#{domain},dc=#{tld}" -p SimpleLdapAuthenticator.valid?('admin', 'adminpassword') +p SimpleLdapAuthenticator.valid?(user, password) diff --git a/examples/rbslapd4.rb b/examples/rbslapd4.rb index 5e704a1..59c3e3c 100644 --- a/examples/rbslapd4.rb +++ b/examples/rbslapd4.rb @@ -49,7 +49,7 @@ router = LDAP::Server::Router.new($logger) do # Bind a route using variables. A hash with the variables will be passed # 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' search nil => 'LDAPController#search' diff --git a/examples/server.rb b/examples/server.rb new file mode 100644 index 0000000..607d7b7 --- /dev/null +++ b/examples/server.rb @@ -0,0 +1,93 @@ +#!/usr/local/bin/ruby -w + +# This is a modified version of rbslapd1.rb which uses a Router instead of +# subclassing the LDAP::Server::Operation class. + +# This is a trivial LDAP server which just stores directory entries in RAM. +# It does no validation or authentication. This is intended just to +# demonstrate the API, it's not for real-world use!! + +$:.unshift('../lib') +$debug = false + +require 'ldap/server' +require 'ldap/server/router' + +$logger = Logger.new($stderr) + +class LDAPController + def self.bind(request, version, dn, password, params) + $logger.debug 'Catchall bind request' + raise LDAP::ResultError::UnwillingToPerform, 'Invalid bind DN' + end + + def self.bindUser(request, version, dn, password, params) + user = params[:uid] + domain = params[:domain] + tld = params[:tld] + + # p "bindUser user=#{user} dn=#{dn}, password=#{password}, params=#{params}" + if user.length < 2 + $logger.warn "Denied access for user #{user}: Size < 2" + raise LDAP::ResultError::InvalidCredentials, 'Invalid credentials' + end + + $logger.info "Authenticated email=#{user}@#{domain}.#{tld} with password=" + 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) + $logger.info 'Search users' + end +end + +router = LDAP::Server::Router.new($logger) do + # Different syntax but same thing + # bind nil => 'LDAPController#bind' + # route :bind, nil => 'LDAPController#bind' + + # Bind a route using variables. A hash with the variables will be passed + # to your function as last argument. + # bind 'uid=:uid,ou=Users,dc=mydomain,dc=com' => 'LDAPController#bindUser' + bind 'uid=:uid,ou=Users,dc=:domain,dc=:tld' => 'LDAPController#bindUser' + + # search nil => 'LDAPController#search' + # search 'ou=Users,dc=mydomain,dc=com' => 'LDAPController#searchUsers' +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 = {} + +# Let's put some backing store on it + +require 'yaml' +begin + File.open('ldapdb.yaml') { |f| directory = YAML.load(f.read) } +rescue Errno::ENOENT +end + +at_exit do + File.open('ldapdb.new', 'w') { |f| f.write(YAML.dump(directory)) } + File.rename('ldapdb.new', 'ldapdb.yaml') +end + +# 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, + # :ssl_key_file => "key.pem", + # :ssl_cert_file => "cert.pem", + # :ssl_on_connect => true, + router: router +) +s.run_tcpserver +s.join