Browse Source

build insert and delete ldif files - still missing for mailAlias and mailAccount

master
Georg Hopp 15 years ago
committed by Georg Hopp
parent
commit
56b9c94ac1
  1. 222
      SystemDataBackendLdap.rb

222
SystemDataBackendLdap.rb

@ -1,100 +1,108 @@
require 'active_support/secure_random'
require 'net/ldap'
class SystemDataBackendLdap
LDAP_USER_MAP = {
:uid => :name,
:userpassword => :pass,
:uidnumber => :uid,
:gidnumber => :gid,
:loginshell => :shell,
:homedirectory => :home
}
LDAP_GROUP_MAP = {
:cn => :name,
:gidnumber => :gid,
:memberuid => :members
}
LDAP_SITE_MAP = {:o => :name}
LDAP_MAP = {
:User => LDAP_USER_MAP,
:Group => LDAP_GROUP_MAP,
:Site => LDAP_SITE_MAP
}
LDAP_FILTER = {
:User => Net::LDAP::Filter::eq('objectClass', 'posixAccount'),
:Group => Net::LDAP::Filter::eq('objectClass', 'posixGroup'),
:Site => Net::LDAP::Filter::eq('objectClass', 'organization') &
(~Net::LDAP::Filter::eq('o', 'hosting')),
:MailAlias => Net::LDAP::Filter::eq('objectClass', 'mailAlias'),
:MailAccount => Net::LDAP::Filter::eq('objectClass', 'mailAccount')
}
LDAP_OBJECTCLASS = {
:User => [ 'account', 'posixAccount', 'shadowAccount' ],
:Group => 'posixGroup'
}
LDAP_LAMBDA_USER = lambda do |entry|
entry[:cn] = entry[:uid]
entry[:shadowlastchange] = (Time::now.to_i/60/60/24).to_s
entry[:replace] += ['shadowreplace'] if entry[:replace]
end
require 'active_support/secure_random'
require 'net/ldap'
class SystemDataBackendLdap
LDAP_USER_MAP = {
:uid => :name,
:userpassword => :pass,
:uidnumber => :uid,
:gidnumber => :gid,
:loginshell => :shell,
:homedirectory => :home
}
LDAP_GROUP_MAP = {
:cn => :name,
:gidnumber => :gid,
:memberuid => :members
}
LDAP_SITE_MAP = {:o => :name}
LDAP_MAP = {
:User => LDAP_USER_MAP,
:Group => LDAP_GROUP_MAP,
:Site => LDAP_SITE_MAP
}
LDAP_FILTER = {
:User => Net::LDAP::Filter::eq('objectClass', 'posixAccount'),
:Group => Net::LDAP::Filter::eq('objectClass', 'posixGroup'),
:Site => Net::LDAP::Filter::eq('objectClass', 'organization') &
(~Net::LDAP::Filter::eq('o', 'hosting')),
:MailAlias => Net::LDAP::Filter::eq('objectClass', 'mailAlias'),
:MailAccount => Net::LDAP::Filter::eq('objectClass', 'mailAccount')
}
LDAP_OBJECTCLASS = {
:User => [ 'account', 'posixAccount', 'shadowAccount' ],
:Group => 'posixGroup',
:Site => 'organization'
}
LDAP_LAMBDA_USER = lambda do |entry|
entry[:cn] = entry[:uid]
entry[:shadowlastchange] = (Time::now.to_i/60/60/24).to_s
entry[:replace] += ['shadowreplace'] if entry[:replace]
end
LDAP_LAMBDA = {
:User => LDAP_LAMBDA_USER
}
LDAP_LAMBDA = {
:User => LDAP_LAMBDA_USER
}
def initialize(host, port, baseDn, args={})
@baseDn = baseDn
@systemDn = 'o=system,' + @baseDn
@hostingDn = 'o=hosting,' + @baseDn
def initialize(host, port, baseDn, args={})
@baseDn = baseDn
@systemDn = 'o=system,' + @baseDn
@hostingDn = 'o=hosting,' + @baseDn
@systemDn = args[:systemDn] if args[:systemDn]
@hostingDn = args[:hostingDn] if args[:hostingDn]
@systemDn = args[:systemDn] if args[:systemDn]
@hostingDn = args[:hostingDn] if args[:hostingDn]
@ldap = Net::LDAP.new(:host => host, :port => port)
@ldapData = Hash.new
end
@ldap = Net::LDAP.new(:host => host, :port => port)
@ldapData = Hash.new
end
def load!(kind)
@ldapData[kind] = Hash.new if ! @ldapData[kind]
def load!(kind)
@ldapData[kind] = Hash.new if ! @ldapData[kind]
@ldapData[kind][:internal] = @ldap.search(
:base => ldapBase(kind),
:filter => LDAP_FILTER[kind]
)
end
@ldapData[kind][:internal] = @ldap.search(
:base => ldapBase(kind),
:filter => LDAP_FILTER[kind]
)
end
def load(kind)
load!(kind) if ! @ldapData[kind]
def load(kind)
load!(kind) if ! @ldapData[kind]
@ldapData[kind][:external] = @ldapData[kind][:internal].map do |data|
map = { :dn => :id }
map.merge!(LDAP_MAP[kind]) if LDAP_MAP[kind]
@ldapData[kind][:external] = @ldapData[kind][:internal].map do |data|
map = { :dn => :id }
map.merge!(LDAP_MAP[kind]) if LDAP_MAP[kind]
ydata = {}
data.each do |key,value|
ydata.merge!({ map[key] || key => value.size==1?value[0]:value.to_a })
end
ydata
end if ! @ldapData[kind][:external]
ydata = {}
data.each do |key,value|
ydata.merge!({ map[key] || key => value.size==1?value[0]:value.to_a })
end
ydata
end if ! @ldapData[kind][:external]
@ldapData[kind][:external].each{|ydata| yield ydata}
@ldapData[kind][:external].each{|ydata| yield ydata}
end
def update(kind, data)
map = {}
map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
entry = Net::LDAP::Entry.new(data[:id])
odata = @ldapData[kind][:external].find{|edata| edata[:id] == data[:id]}
data.each do |key,value|
pat_key = map[key] ? map[key] : key
if odata[:id] =~ /(^|, *)#{pat_key.to_s}=([^, ]+)/ && $2 != value
return replace(kind, data)
end
end
entry = Net::LDAP::Entry.new(data[:id])
data = data.find_all{|key,value| value != odata[key]}
data.delete(:id)
@ -105,17 +113,52 @@ class SystemDataBackendLdap
entry[key] = value
end
if not replace.empty?
if replace.empty?
puts 'INFO: no changes'
else
entry[:changetype] = 'modify'
entry[:replace] = replace
LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
puts entry.to_ldif
else
puts 'INFO: no changes'
end
end
def replace(kind, data)
puts 'INFO: do replace'
puts '----------------'
odata = @ldapData[kind][:external].find{|edata| edata[:id] == data[:id]}
delete(odata)
puts
insert(kind, data)
puts '----------------'
end
def delete(data)
entry = Net::LDAP::Entry.new(data[:id])
entry[:changetype] = 'delete'
puts entry.to_ldif
end
def insert(kind, data)
map = {}
map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind]
data.delete(:id)
entry = Net::LDAP::Entry.new(ldapDn(kind, data))
entry[:changetype] = 'add'
entry[:objectclass] = LDAP_OBJECTCLASS[kind]
data.each do |key,value|
key = map[key] if map[key]
entry[key] = value
end
LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind]
puts entry.to_ldif
end
private
def ldapBase(kind)
@ -125,4 +168,17 @@ class SystemDataBackendLdap
end
end
def ldapDn(kind, data)
case(kind)
when :User
"uid=#{data[:name]},ou=user,#{ldapBase(kind)}"
when :Group
"cn=#{data[:name]},ou=group,#{ldapBase(kind)}"
when :Site
"o=#{data[:name]},#{ldapBase(kind)}"
else
"not yet implemented"
end
end
end
Loading…
Cancel
Save