diff --git a/lib/ildus/server/backend.rb b/lib/ildus/server/backend.rb index 237b5c9..77d2056 100644 --- a/lib/ildus/server/backend.rb +++ b/lib/ildus/server/backend.rb @@ -17,25 +17,21 @@ module Ildus BackendClasses = Hash.new - class << self + def self.load + path = File.dirname(__FILE__) + Dir["#{path}/backends/**/*.rb"].each { |file| require file } + end - def load - path = File.dirname(__FILE__) - Dir["#{path}/backends/**/*.rb"].each { |file| require file } + def self.get(type) + BackendClasses[type.to_sym] + end + alias_method :[], :get + + def self.register(type, backend_class) + if BackendClasses.include? type + raise "type #{type} already registered" end - - def get(type) - BackendClasses[type.to_sym] - end - alias_method :[], :get - - def register(type, backend_class) - if BackendClasses.include? type - raise "type #{type} already registered" - end - BackendClasses[type] = backend_class - end - + BackendClasses[type] = backend_class end class Basic @@ -59,22 +55,25 @@ module Ildus # 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") - ## + authenticate end def authenticated? @auth end + ################# + # Backend methods + + def authenticate + raise Handler::NotImplementedError + end + def register_account raise Handler::NotImplementedError end @@ -83,22 +82,19 @@ module Ildus raise Handler::NotImplementedError end - ################# - # Backend methods - - def hostnames + def hosts raise Handler::NotImplementedError end - def add_hostname(host) + def add_host(host) raise Handler::NotImplementedError end - def remove_hostname(host) + def remove_host(host) raise Handler::NotImplementedError end - def update_hostname(host, addr) + def update_host(host, addr) raise Handler::NotImplementedError end diff --git a/lib/ildus/server/backends/ldap.rb b/lib/ildus/server/backends/ldap.rb index 723abd0..4711448 100644 --- a/lib/ildus/server/backends/ldap.rb +++ b/lib/ildus/server/backends/ldap.rb @@ -20,31 +20,53 @@ module Ildus::Server::Backend @ldap.simple_bind(config['user'], config['pass']) end - def hostnames + def authenticate + ## STUB + @auth = (@pass == "foo") + ## + end + + def hosts entries = Hash.new { |h, k| h[k] = [[], []] } - @ldap.search(config['base'], LDAP::LDAP_SCOPE_SUBTREE, - "ildusOwner=#{user}") do |entry| + + all_entries.each do |entry| assoc_dom, a_rr, aaaa_rr, cname_rr = ["associatedDomain", "aRecord", - "aAAArecord", "cNAMErecord"].map do |attr| - entry.vals(attr) - end - + "aAAArecord", "cNAMErecord"].map { |attr| entry[attr] } 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 + + entries[host].first.push(*a_rr) if a_rr + entries[host].first.push(*aaaa_rr) if aaaa_rr if cname_rr cname = cname_rr.first.gsub(/\.#{config['domain']}$/, '') entries[cname].last << host end - end + end # search return entries - end # hostnames + end # def hosts + + def update_host(host, addr) + entry = all_entries.find do |entry| + entry['associatedDomain'][0] == host + "." + config['domain'] + end + raise Handler::HostNotFoundError if entry.nil? + + if addr.ipv4? + @ldap.modify(entry['dn'][0], {"aRecord" => [addr.to_s]}) + elsif addr.ipv6? + @ldap.modify(entry['dn'][0], {"aAAARecord" => [addr.to_s]}) + end + end + + ######### + private + ######### + + def all_entries + @ldap.search2(config['base'], LDAP::LDAP_SCOPE_SUBTREE, + "(&(objectClass=ildusRecord)(ildusOwner=#{user}))") + end end # class LDAPv3 diff --git a/lib/ildus/server/handler.rb b/lib/ildus/server/handler.rb index d490c8b..7ea9000 100644 --- a/lib/ildus/server/handler.rb +++ b/lib/ildus/server/handler.rb @@ -7,6 +7,8 @@ # Software Foundation; either version 2 of the License, or (at your option) # any later version. +require 'ipaddr' + require 'ildus/server/backend' module Ildus @@ -63,11 +65,12 @@ module Ildus def initialize(server, io) @server = server + @config = server.config @io = io - type = server.config["backend"]["type"] - klass = Backend[server.config["backend"]["type"]] + type = @config["backend"]["type"] + klass = Backend[@config["backend"]["type"]] raise "backend type `#{type}' not found" if klass.nil? - @backend = klass.new(server.config["backend"]) + @backend = klass.new(@config["backend"]) rescue => msg prot_msg 505, msg raise @@ -141,14 +144,16 @@ module Ildus # Commands methods def user_cmd(username) + raise AlreadyAuthError if @backend.authenticated? @backend.user = username prot_msg 331 end def pass_cmd(password) raise SetUserFirstError unless @backend.user - + raise AlreadyAuthError if @backend.authenticated? @backend.pass = password + if @backend.authenticated? prot_msg 230, @backend.user else @@ -156,42 +161,41 @@ module Ildus end end - def updt_cmd(hostname, addr) + def updt_cmd(host, addr) raise NotAuthError unless @backend.authenticated? - @backend.update_hostname(@backend.user, hostname, addr) + addr = IPAddr.new(addr) + @backend.update_host(host, addr) rescue HostNotFoundError - prot_msg 425, hostname + prot_msg 425, host rescue RecordNotFoundError - prot_msg 426, type, hostname + prot_msg 426, type, host else - prot_msg 240, hostname, addr + prot_msg 240, host, addr end - def adda_cmd(hostname, new_alias) + def adda_cmd(host, new_alias) raise NotImplementedError end - def dela_cmd(hostname, old_alias) + def dela_cmd(host, old_alias) raise NotImplementedError end def list_cmd 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 + list = @backend.hosts.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" + - h.to_yaml + "\n" + list.to_yaml + "\n" end def help_cmd - prot_msg_with_body 214, - <<-EOT, "ildus-admin@localhost" + prot_msg_with_body 214, <<-EOT, "ildus-admin@localhost" The following commands are recognized: HELP\t\t\tshow this help QUIT\t\t\tclose connection