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[:shadowmax] = '99999' entry[:shadowwarning] = '7' end LDAP_LAMBDA = { :User => LDAP_LAMBDA_USER } 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] @ldap = Net::LDAP.new(:host => host, :port => port) @ldapData = Hash.new end def load!(kind) @ldapData[kind] = @ldap.search( :base => ldapBase(kind), :filter => LDAP_FILTER[kind] ) end def load(kind) load!(kind) if ! @ldapData[kind] @ldapData[kind].each 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 yield ydata end end def update(kind, data) map = {} map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind] entry = Net::LDAP::Entry.new(data[:id]) data.delete(:id) 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) case(kind) when :User, :Group: @systemDn when :Site, :MailAlias, :MailAccount: @hostingDn end end end