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
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
|
class Basic
|
||||||
|
|
||||||
|
attr_reader :config, :user, :pass
|
||||||
|
|
||||||
def self.inherited(subclass)
|
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)
|
Backend.register(type, subclass)
|
||||||
end
|
end
|
||||||
|
|
||||||
def hostnames_of(user)
|
def initialize(backend_config)
|
||||||
|
@config = backend_config
|
||||||
|
@auth = false
|
||||||
|
@user = user
|
||||||
|
@pass = pass
|
||||||
|
end
|
||||||
|
|
||||||
|
#################
|
||||||
|
# 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
|
raise Handler::NotImplementedError
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_hostname(user)
|
def unregister_account
|
||||||
raise Handler::NotImplementedError
|
raise Handler::NotImplementedError
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_hostname(user)
|
#################
|
||||||
|
# Backend methods
|
||||||
|
|
||||||
|
def hostnames
|
||||||
raise Handler::NotImplementedError
|
raise Handler::NotImplementedError
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_hostname(user, host, addr)
|
def add_hostname(host)
|
||||||
raise Handler::NotImplementedError
|
raise Handler::NotImplementedError
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_alias(user, new_alias, host)
|
def remove_hostname(host)
|
||||||
raise Handler::NotImplementedError
|
raise Handler::NotImplementedError
|
||||||
end
|
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
|
raise Handler::NotImplementedError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,45 @@
|
||||||
# Software Foundation; either version 2 of the License, or (at your option)
|
# Software Foundation; either version 2 of the License, or (at your option)
|
||||||
# any later version.
|
# any later version.
|
||||||
|
|
||||||
|
require 'ldap'
|
||||||
|
|
||||||
module Ildus::Server::Backend
|
module Ildus::Server::Backend
|
||||||
|
|
||||||
class LDAP < Basic
|
class LDAPv3 < Basic
|
||||||
|
|
||||||
|
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
|
end
|
||||||
|
|
||||||
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)
|
# Software Foundation; either version 2 of the License, or (at your option)
|
||||||
# any later version.
|
# any later version.
|
||||||
|
|
||||||
require 'ildus/server/account'
|
|
||||||
require 'ildus/server/backend'
|
require 'ildus/server/backend'
|
||||||
|
|
||||||
module Ildus
|
module Ildus
|
||||||
|
@ -65,11 +64,13 @@ module Ildus
|
||||||
def initialize(server, io)
|
def initialize(server, io)
|
||||||
@server = server
|
@server = server
|
||||||
@io = io
|
@io = io
|
||||||
@account = Account.new
|
|
||||||
type = server.config["backend"]["type"]
|
type = server.config["backend"]["type"]
|
||||||
klass = Backend[server.config["backend"]["type"]]
|
klass = Backend[server.config["backend"]["type"]]
|
||||||
raise "backend type `#{type}' not found" if klass.nil?
|
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
|
end
|
||||||
|
|
||||||
def handle_client
|
def handle_client
|
||||||
|
@ -140,24 +141,24 @@ module Ildus
|
||||||
# Commands methods
|
# Commands methods
|
||||||
|
|
||||||
def user_cmd(username)
|
def user_cmd(username)
|
||||||
@account.user = username
|
@backend.user = username
|
||||||
prot_msg 331
|
prot_msg 331
|
||||||
end
|
end
|
||||||
|
|
||||||
def pass_cmd(password)
|
def pass_cmd(password)
|
||||||
raise SetUserFirstError unless @account.user
|
raise SetUserFirstError unless @backend.user
|
||||||
|
|
||||||
@account.pass = password
|
@backend.pass = password
|
||||||
if @account.authenticated?
|
if @backend.authenticated?
|
||||||
prot_msg 230, @account.user
|
prot_msg 230, @backend.user
|
||||||
else
|
else
|
||||||
raise NotAuthError
|
raise NotAuthError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def updt_cmd(hostname, addr)
|
def updt_cmd(hostname, addr)
|
||||||
raise NotAuthError unless @account.authenticated?
|
raise NotAuthError unless @backend.authenticated?
|
||||||
@backend.update_hostname(@account.user, hostname, addr)
|
@backend.update_hostname(@backend.user, hostname, addr)
|
||||||
rescue HostNotFoundError
|
rescue HostNotFoundError
|
||||||
prot_msg 425, hostname
|
prot_msg 425, hostname
|
||||||
rescue RecordNotFoundError
|
rescue RecordNotFoundError
|
||||||
|
@ -175,11 +176,17 @@ module Ildus
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_cmd
|
def list_cmd
|
||||||
raise NotAuthError unless @account.authenticated?
|
raise NotAuthError unless @backend.authenticated?
|
||||||
user = @account.user
|
user = @backend.user
|
||||||
#list = @backend.hostnames_of(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,
|
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
|
end
|
||||||
|
|
||||||
def help_cmd
|
def help_cmd
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
require 'stringio'
|
||||||
require 'test/unit'
|
require 'test/unit'
|
||||||
require 'ildus/server'
|
require 'ildus/server'
|
||||||
|
|
||||||
|
@ -12,7 +13,7 @@ class TC_HandlerTest < Test::Unit::TestCase
|
||||||
assert(@hdl)
|
assert(@hdl)
|
||||||
|
|
||||||
class << @hdl
|
class << @hdl
|
||||||
attr_reader :account
|
attr_reader :backend
|
||||||
public :handle_command
|
public :handle_command
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -28,28 +29,28 @@ class TC_HandlerTest < Test::Unit::TestCase
|
||||||
|
|
||||||
# Set the user.
|
# Set the user.
|
||||||
@hdl.handle_command("user", ["test"])
|
@hdl.handle_command("user", ["test"])
|
||||||
assert_equal("test", @hdl.account.user)
|
assert_equal("test", @hdl.backend.user)
|
||||||
|
|
||||||
# "list" still shouldn't be possible.
|
# "list" still shouldn't be possible.
|
||||||
assert_raises(Server::Handler::NotAuthError) { @hdl.handle_command("list") }
|
assert_raises(Server::Handler::NotAuthError) { @hdl.handle_command("list") }
|
||||||
|
|
||||||
# Set a different user.
|
# Set a different user.
|
||||||
@hdl.handle_command("user", ["test2"])
|
@hdl.handle_command("user", ["test2"])
|
||||||
assert_equal("test2", @hdl.account.user)
|
assert_equal("test2", @hdl.backend.user)
|
||||||
|
|
||||||
# Give an incorrect password.
|
# Give an incorrect password.
|
||||||
assert_raises(Server::Handler::NotAuthError) do
|
assert_raises(Server::Handler::NotAuthError) do
|
||||||
@hdl.handle_command("pass", ["secret"])
|
@hdl.handle_command("pass", ["secret"])
|
||||||
end
|
end
|
||||||
assert_equal("secret", @hdl.account.pass)
|
assert_equal("secret", @hdl.backend.pass)
|
||||||
|
|
||||||
# Nothing should be raised when setting the password,
|
# Nothing should be raised when setting the password,
|
||||||
# we should be authenticated afterwards.
|
# we should be authenticated afterwards.
|
||||||
assert_nothing_raised do
|
assert_nothing_raised do
|
||||||
@hdl.handle_command("pass", ["foo"])
|
@hdl.handle_command("pass", ["foo"])
|
||||||
end
|
end
|
||||||
assert_equal("foo", @hdl.account.pass)
|
assert_equal("foo", @hdl.backend.pass)
|
||||||
assert(@hdl.account.authenticated?)
|
assert(@hdl.backend.authenticated?)
|
||||||
|
|
||||||
# "list" should be possible now.
|
# "list" should be possible now.
|
||||||
assert_nothing_raised do
|
assert_nothing_raised do
|
||||||
|
|
Reference in a new issue