SystemDataBackendLdap.rb
3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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
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] = Hash.new if ! @ldapData[kind]
@ldapData[kind][:internal] = @ldap.search(
:base => ldapBase(kind),
:filter => LDAP_FILTER[kind]
)
end
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]
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}
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 = data.find_all{|key,value| value != odata[key]}
data.delete(:id)
replace = Array.new
data.each do |key,value|
key = map[key] if map[key]
replace.push(key.to_s)
entry[key] = value
end
if not replace.empty?
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
private
def ldapBase(kind)
case(kind)
when :User, :Group: @systemDn
when :Site, :MailAlias, :MailAccount: @hostingDn
end
end
end