Implemented some parts of the LDAPv3 backend, moved account stuff:
* Merged Account with Backend::Basic. * Adapted the Handler and Backend for this change. * Implemented parts of Backend::LDAPv3 (init, hostnames). * Add auxiliary ildus.schema. * Fixed unit tests. git-svn-id: svn+ssh://svn.luon.net/svn/ildus/trunk@9 65a33f86-aa00-0410-91be-cd1bf5efb309
This commit is contained in:
parent
787f6fc97e
commit
40bc5d22a3
5 changed files with 126 additions and 30 deletions
11
doc/schema/ildus.schema
Normal file
11
doc/schema/ildus.schema
Normal file
|
@ -0,0 +1,11 @@
|
|||
# A schema for handling ownership of Ildus DNS records for
|
||||
# storing DNS zones in LDAP
|
||||
#
|
||||
attributetype ( 1.3.6.1.4.1.4203.666.1.4096 NAME 'ildusOwner'
|
||||
DESC 'Owner of the Ildus dNSDomain2 record'
|
||||
SUP name )
|
||||
|
||||
objectclass ( 1.3.6.1.4.1.4203.666.3.4096 NAME 'ildusRecord'
|
||||
DESC 'A dNSDomain2 record that is updatable via Ildus'
|
||||
SUP top AUXILIARY
|
||||
MUST ildusOwner )
|
|
@ -40,32 +40,73 @@ module Ildus
|
|||
|
||||
class Basic
|
||||
|
||||
attr_reader :config, :user, :pass
|
||||
|
||||
def self.inherited(subclass)
|
||||
type = subclass.to_s.split('::').last.downcase.to_sym
|
||||
diff = subclass.to_s.split('::') - self.to_s.split('::')
|
||||
type = diff.to_s.split('::').last.downcase.to_sym
|
||||
Backend.register(type, subclass)
|
||||
end
|
||||
|
||||
def initialize(backend_config)
|
||||
@config = backend_config
|
||||
@auth = false
|
||||
@user = user
|
||||
@pass = pass
|
||||
end
|
||||
|
||||
def hostnames_of(user)
|
||||
#################
|
||||
# Account methods
|
||||
|
||||
def user=(username)
|
||||
raise Handler::AlreadyAuthError if @auth
|
||||
@user = username
|
||||
end
|
||||
|
||||
def pass=(password)
|
||||
raise Handler::AlreadyAuthError if @auth
|
||||
@pass = password
|
||||
## STUB
|
||||
@auth = (password == "foo")
|
||||
##
|
||||
end
|
||||
|
||||
def authenticated?
|
||||
@auth
|
||||
end
|
||||
|
||||
def register_account
|
||||
raise Handler::NotImplementedError
|
||||
end
|
||||
|
||||
def add_hostname(user)
|
||||
def unregister_account
|
||||
raise Handler::NotImplementedError
|
||||
end
|
||||
|
||||
def remove_hostname(user)
|
||||
#################
|
||||
# Backend methods
|
||||
|
||||
def hostnames
|
||||
raise Handler::NotImplementedError
|
||||
end
|
||||
|
||||
def update_hostname(user, host, addr)
|
||||
def add_hostname(host)
|
||||
raise Handler::NotImplementedError
|
||||
end
|
||||
|
||||
def add_alias(user, new_alias, host)
|
||||
def remove_hostname(host)
|
||||
raise Handler::NotImplementedError
|
||||
end
|
||||
|
||||
def remove_alias(user, old_alias, host)
|
||||
def update_hostname(host, addr)
|
||||
raise Handler::NotImplementedError
|
||||
end
|
||||
|
||||
def add_alias(new_alias, host)
|
||||
raise Handler::NotImplementedError
|
||||
end
|
||||
|
||||
def remove_alias(old_alias, host)
|
||||
raise Handler::NotImplementedError
|
||||
end
|
||||
|
||||
|
|
|
@ -7,9 +7,45 @@
|
|||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
|
||||
require 'ldap'
|
||||
|
||||
module Ildus::Server::Backend
|
||||
|
||||
class LDAP < Basic
|
||||
end
|
||||
class LDAPv3 < Basic
|
||||
|
||||
end
|
||||
def initialize(*args)
|
||||
super
|
||||
@ldap = LDAP::Conn.new(config['host'])
|
||||
@ldap.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION, 3)
|
||||
@ldap.simple_bind(config['user'], config['pass'])
|
||||
end
|
||||
|
||||
def hostnames
|
||||
entries = Hash.new { |h, k| h[k] = [[], []] }
|
||||
@ldap.search(config['base'], LDAP::LDAP_SCOPE_SUBTREE,
|
||||
"ildusOwner=#{user}") do |entry|
|
||||
assoc_dom, a_rr, aaaa_rr, cname_rr =
|
||||
["associatedDomain", "aRecord",
|
||||
"aAAArecord", "cNAMErecord"].map do |attr|
|
||||
entry.vals(attr)
|
||||
end
|
||||
|
||||
host = assoc_dom.first.gsub(/\.#{config['domain']}$/, '')
|
||||
if a_rr
|
||||
entries[host].first.push(*a_rr)
|
||||
end
|
||||
if aaaa_rr
|
||||
entries[host].first.push(*aaaa_rr)
|
||||
end
|
||||
if cname_rr
|
||||
cname = cname_rr.first.gsub(/\.#{config['domain']}$/, '')
|
||||
entries[cname].last << host
|
||||
end
|
||||
end
|
||||
|
||||
return entries
|
||||
end # hostnames
|
||||
|
||||
end # class LDAPv3
|
||||
|
||||
end # module Ildus::Server::Backend
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
|
||||
require 'ildus/server/account'
|
||||
require 'ildus/server/backend'
|
||||
|
||||
module Ildus
|
||||
|
@ -65,11 +64,13 @@ module Ildus
|
|||
def initialize(server, io)
|
||||
@server = server
|
||||
@io = io
|
||||
@account = Account.new
|
||||
type = server.config["backend"]["type"]
|
||||
klass = Backend[server.config["backend"]["type"]]
|
||||
raise "backend type `#{type}' not found" if klass.nil?
|
||||
@backend = klass.new
|
||||
@backend = klass.new(server.config["backend"])
|
||||
rescue => msg
|
||||
prot_msg 505, msg
|
||||
raise
|
||||
end
|
||||
|
||||
def handle_client
|
||||
|
@ -140,24 +141,24 @@ module Ildus
|
|||
# Commands methods
|
||||
|
||||
def user_cmd(username)
|
||||
@account.user = username
|
||||
@backend.user = username
|
||||
prot_msg 331
|
||||
end
|
||||
|
||||
def pass_cmd(password)
|
||||
raise SetUserFirstError unless @account.user
|
||||
raise SetUserFirstError unless @backend.user
|
||||
|
||||
@account.pass = password
|
||||
if @account.authenticated?
|
||||
prot_msg 230, @account.user
|
||||
@backend.pass = password
|
||||
if @backend.authenticated?
|
||||
prot_msg 230, @backend.user
|
||||
else
|
||||
raise NotAuthError
|
||||
end
|
||||
end
|
||||
|
||||
def updt_cmd(hostname, addr)
|
||||
raise NotAuthError unless @account.authenticated?
|
||||
@backend.update_hostname(@account.user, hostname, addr)
|
||||
raise NotAuthError unless @backend.authenticated?
|
||||
@backend.update_hostname(@backend.user, hostname, addr)
|
||||
rescue HostNotFoundError
|
||||
prot_msg 425, hostname
|
||||
rescue RecordNotFoundError
|
||||
|
@ -175,11 +176,17 @@ module Ildus
|
|||
end
|
||||
|
||||
def list_cmd
|
||||
raise NotAuthError unless @account.authenticated?
|
||||
user = @account.user
|
||||
#list = @backend.hostnames_of(user)
|
||||
raise NotAuthError unless @backend.authenticated?
|
||||
user = @backend.user
|
||||
list = @backend.hostnames
|
||||
h = list.inject(Hash.new) do |memo, (host, info)|
|
||||
memo[host] = {"addresses" => info.first, "aliases" => info.last}
|
||||
memo
|
||||
end
|
||||
|
||||
prot_msg_with_body 215,
|
||||
"Listing of hosts (and aliases) for user #{user}\n"
|
||||
"Listing of hosts (and aliases) for user #{user}\n" +
|
||||
h.to_yaml + "\n"
|
||||
end
|
||||
|
||||
def help_cmd
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require 'stringio'
|
||||
require 'test/unit'
|
||||
require 'ildus/server'
|
||||
|
||||
|
@ -12,7 +13,7 @@ class TC_HandlerTest < Test::Unit::TestCase
|
|||
assert(@hdl)
|
||||
|
||||
class << @hdl
|
||||
attr_reader :account
|
||||
attr_reader :backend
|
||||
public :handle_command
|
||||
end
|
||||
end
|
||||
|
@ -28,28 +29,28 @@ class TC_HandlerTest < Test::Unit::TestCase
|
|||
|
||||
# Set the user.
|
||||
@hdl.handle_command("user", ["test"])
|
||||
assert_equal("test", @hdl.account.user)
|
||||
assert_equal("test", @hdl.backend.user)
|
||||
|
||||
# "list" still shouldn't be possible.
|
||||
assert_raises(Server::Handler::NotAuthError) { @hdl.handle_command("list") }
|
||||
|
||||
# Set a different user.
|
||||
@hdl.handle_command("user", ["test2"])
|
||||
assert_equal("test2", @hdl.account.user)
|
||||
assert_equal("test2", @hdl.backend.user)
|
||||
|
||||
# Give an incorrect password.
|
||||
assert_raises(Server::Handler::NotAuthError) do
|
||||
@hdl.handle_command("pass", ["secret"])
|
||||
end
|
||||
assert_equal("secret", @hdl.account.pass)
|
||||
assert_equal("secret", @hdl.backend.pass)
|
||||
|
||||
# Nothing should be raised when setting the password,
|
||||
# we should be authenticated afterwards.
|
||||
assert_nothing_raised do
|
||||
@hdl.handle_command("pass", ["foo"])
|
||||
end
|
||||
assert_equal("foo", @hdl.account.pass)
|
||||
assert(@hdl.account.authenticated?)
|
||||
assert_equal("foo", @hdl.backend.pass)
|
||||
assert(@hdl.backend.authenticated?)
|
||||
|
||||
# "list" should be possible now.
|
||||
assert_nothing_raised do
|
||||
|
|
Reference in a new issue