134 lines
4.2 KiB
Ruby
134 lines
4.2 KiB
Ruby
# = ildus/server/backend - ldap domain backend library
|
|
#
|
|
# Copyright (C) 2005 Paul van Tilburg <paul@luon.net>
|
|
#
|
|
# Ildus is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free
|
|
# Software Foundation; either version 2 of the License, or (at your option)
|
|
# any later version.
|
|
|
|
require 'ldap'
|
|
|
|
module Ildus::Server::DomainBackend
|
|
|
|
# = LDAP domain backend
|
|
#
|
|
# The domain backend class that uses an LDAP database. It uses the LDAP
|
|
# record format used by the PowerDNS backend. (see:
|
|
# http://www.linuxnetworks.de/pdnsldap/dnsdomain2.schema) Next to that it
|
|
# uses an extra ildusOwner field to couple LDAP dNSdomain records to
|
|
# users.
|
|
class Ldap < Basic
|
|
|
|
# Sets up the LDAP backend by switching to LDAPv3 protocol
|
|
# and binding to the server.
|
|
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
|
|
|
|
# Updates the serial on the SOA record and calls the inherited
|
|
# commit (invoking the hook).
|
|
def commit
|
|
update_serial
|
|
super
|
|
end
|
|
|
|
# Returns the list (a Hash actually) of hosts for the selected user.
|
|
# It looks for A, AAAA and CNAME records.
|
|
def hosts
|
|
entries = Hash.new { |h, k| h[k] = [[], []] }
|
|
|
|
all_entries.each do |entry|
|
|
assoc_dom, a_rr, aaaa_rr, cname_rr =
|
|
["associatedDomain", "aRecord",
|
|
"aAAArecord", "cNAMErecord"].map { |attr| entry[attr] }
|
|
host = assoc_dom.first.gsub(/\.#{config['domain']}$/, '')
|
|
|
|
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 # search
|
|
|
|
return entries
|
|
end # def hosts
|
|
|
|
# Updates the address of _host_ to _addr_ providing that _addr_ is in a
|
|
# correct IPv4 or IPv6 address format.
|
|
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]})
|
|
else
|
|
return false
|
|
end
|
|
|
|
true
|
|
end
|
|
|
|
#########
|
|
private
|
|
#########
|
|
|
|
# Returns a list of all LDAP IldusRecord entries for the selected
|
|
# user.
|
|
def all_entries
|
|
@ldap.search2(config['base'], LDAP::LDAP_SCOPE_SUBTREE,
|
|
"(&(objectClass=ildusRecord)(ildusOwner=#{user}))")
|
|
end
|
|
|
|
# Returns the LDAP sOARecord for the configured domain.
|
|
def soa_record
|
|
@ldap.search2(config['base'], LDAP::LDAP_SCOPE_BASE,
|
|
"(&(associatedDomain=#{config['domain'].downcase})" \
|
|
" (sOARecord=*))").first
|
|
end
|
|
|
|
# Updates the serial of the SOA record of the configured domain.
|
|
# The serial consists of two parts, the date (yyyymmdd) and
|
|
# counter (nn) part. On every update the date is set to the current
|
|
# date, it will increase the counter.
|
|
#
|
|
# Note that the counter may overflow so that actually the day is
|
|
# incremented. This is no problem unless there is an almost infinite
|
|
# sequance of days with more then 100 updates/day.
|
|
def update_serial
|
|
record = soa_record
|
|
soa = record['sOARecord'].first.split
|
|
soa[2] = serial_succ(soa[2])
|
|
|
|
@ldap.modify(record['dn'][0], {"sOARecord" => [soa.join(" ")]})
|
|
end
|
|
|
|
# Determines the successor of the current serial number, see
|
|
# also #update_serial().
|
|
def serial_succ(serial)
|
|
date, num = serial.scan(/\d{8}|\d{2}/)
|
|
today = Time.now.strftime("%Y%m%d")
|
|
|
|
if (date < today)
|
|
date, num = today, '00'
|
|
elsif (num == '99')
|
|
date, num = date.succ, '00'
|
|
else
|
|
num = num.succ
|
|
end
|
|
|
|
return "%08s%02s" % [date, num]
|
|
end
|
|
|
|
end # class Ldap
|
|
|
|
end # module Ildus::Server::DomainBackend
|