Commit 56b9c94ac19670c1d00374cbe7cb631b95d654c8
Committed by
Georg Hopp
1 parent
85d6aac8
build insert and delete ldif files - still missing for mailAlias and mailAccount
Showing
1 changed file
with
139 additions
and
83 deletions
1 | -require 'active_support/secure_random' | |
2 | -require 'net/ldap' | |
3 | - | |
4 | -class SystemDataBackendLdap | |
5 | - | |
6 | - LDAP_USER_MAP = { | |
7 | - :uid => :name, | |
8 | - :userpassword => :pass, | |
9 | - :uidnumber => :uid, | |
10 | - :gidnumber => :gid, | |
11 | - :loginshell => :shell, | |
12 | - :homedirectory => :home | |
13 | - } | |
14 | - | |
15 | - LDAP_GROUP_MAP = { | |
16 | - :cn => :name, | |
17 | - :gidnumber => :gid, | |
18 | - :memberuid => :members | |
19 | - } | |
20 | - | |
21 | - LDAP_SITE_MAP = {:o => :name} | |
22 | - | |
23 | - LDAP_MAP = { | |
24 | - :User => LDAP_USER_MAP, | |
25 | - :Group => LDAP_GROUP_MAP, | |
26 | - :Site => LDAP_SITE_MAP | |
27 | - } | |
28 | - | |
29 | - LDAP_FILTER = { | |
30 | - :User => Net::LDAP::Filter::eq('objectClass', 'posixAccount'), | |
31 | - :Group => Net::LDAP::Filter::eq('objectClass', 'posixGroup'), | |
32 | - :Site => Net::LDAP::Filter::eq('objectClass', 'organization') & | |
33 | - (~Net::LDAP::Filter::eq('o', 'hosting')), | |
34 | - :MailAlias => Net::LDAP::Filter::eq('objectClass', 'mailAlias'), | |
35 | - :MailAccount => Net::LDAP::Filter::eq('objectClass', 'mailAccount') | |
36 | - } | |
37 | - | |
38 | - LDAP_OBJECTCLASS = { | |
39 | - :User => [ 'account', 'posixAccount', 'shadowAccount' ], | |
40 | - :Group => 'posixGroup' | |
41 | - } | |
42 | - | |
43 | - LDAP_LAMBDA_USER = lambda do |entry| | |
44 | - entry[:cn] = entry[:uid] | |
45 | - entry[:shadowlastchange] = (Time::now.to_i/60/60/24).to_s | |
46 | - entry[:replace] += ['shadowreplace'] if entry[:replace] | |
47 | - end | |
1 | + require 'active_support/secure_random' | |
2 | + require 'net/ldap' | |
3 | + | |
4 | + class SystemDataBackendLdap | |
5 | + | |
6 | + LDAP_USER_MAP = { | |
7 | + :uid => :name, | |
8 | + :userpassword => :pass, | |
9 | + :uidnumber => :uid, | |
10 | + :gidnumber => :gid, | |
11 | + :loginshell => :shell, | |
12 | + :homedirectory => :home | |
13 | + } | |
14 | + | |
15 | + LDAP_GROUP_MAP = { | |
16 | + :cn => :name, | |
17 | + :gidnumber => :gid, | |
18 | + :memberuid => :members | |
19 | + } | |
20 | + | |
21 | + LDAP_SITE_MAP = {:o => :name} | |
22 | + | |
23 | + LDAP_MAP = { | |
24 | + :User => LDAP_USER_MAP, | |
25 | + :Group => LDAP_GROUP_MAP, | |
26 | + :Site => LDAP_SITE_MAP | |
27 | + } | |
28 | + | |
29 | + LDAP_FILTER = { | |
30 | + :User => Net::LDAP::Filter::eq('objectClass', 'posixAccount'), | |
31 | + :Group => Net::LDAP::Filter::eq('objectClass', 'posixGroup'), | |
32 | + :Site => Net::LDAP::Filter::eq('objectClass', 'organization') & | |
33 | + (~Net::LDAP::Filter::eq('o', 'hosting')), | |
34 | + :MailAlias => Net::LDAP::Filter::eq('objectClass', 'mailAlias'), | |
35 | + :MailAccount => Net::LDAP::Filter::eq('objectClass', 'mailAccount') | |
36 | + } | |
37 | + | |
38 | + LDAP_OBJECTCLASS = { | |
39 | + :User => [ 'account', 'posixAccount', 'shadowAccount' ], | |
40 | + :Group => 'posixGroup', | |
41 | + :Site => 'organization' | |
42 | + } | |
43 | + | |
44 | + LDAP_LAMBDA_USER = lambda do |entry| | |
45 | + entry[:cn] = entry[:uid] | |
46 | + entry[:shadowlastchange] = (Time::now.to_i/60/60/24).to_s | |
47 | + entry[:replace] += ['shadowreplace'] if entry[:replace] | |
48 | + end | |
48 | 49 | |
49 | - LDAP_LAMBDA = { | |
50 | - :User => LDAP_LAMBDA_USER | |
51 | - } | |
50 | + LDAP_LAMBDA = { | |
51 | + :User => LDAP_LAMBDA_USER | |
52 | + } | |
52 | 53 | |
53 | - def initialize(host, port, baseDn, args={}) | |
54 | - @baseDn = baseDn | |
55 | - @systemDn = 'o=system,' + @baseDn | |
56 | - @hostingDn = 'o=hosting,' + @baseDn | |
54 | + def initialize(host, port, baseDn, args={}) | |
55 | + @baseDn = baseDn | |
56 | + @systemDn = 'o=system,' + @baseDn | |
57 | + @hostingDn = 'o=hosting,' + @baseDn | |
57 | 58 | |
58 | - @systemDn = args[:systemDn] if args[:systemDn] | |
59 | - @hostingDn = args[:hostingDn] if args[:hostingDn] | |
59 | + @systemDn = args[:systemDn] if args[:systemDn] | |
60 | + @hostingDn = args[:hostingDn] if args[:hostingDn] | |
60 | 61 | |
61 | - @ldap = Net::LDAP.new(:host => host, :port => port) | |
62 | - @ldapData = Hash.new | |
63 | - end | |
62 | + @ldap = Net::LDAP.new(:host => host, :port => port) | |
63 | + @ldapData = Hash.new | |
64 | + end | |
64 | 65 | |
65 | - def load!(kind) | |
66 | - @ldapData[kind] = Hash.new if ! @ldapData[kind] | |
66 | + def load!(kind) | |
67 | + @ldapData[kind] = Hash.new if ! @ldapData[kind] | |
67 | 68 | |
68 | - @ldapData[kind][:internal] = @ldap.search( | |
69 | - :base => ldapBase(kind), | |
70 | - :filter => LDAP_FILTER[kind] | |
71 | - ) | |
72 | - end | |
69 | + @ldapData[kind][:internal] = @ldap.search( | |
70 | + :base => ldapBase(kind), | |
71 | + :filter => LDAP_FILTER[kind] | |
72 | + ) | |
73 | + end | |
73 | 74 | |
74 | - def load(kind) | |
75 | - load!(kind) if ! @ldapData[kind] | |
75 | + def load(kind) | |
76 | + load!(kind) if ! @ldapData[kind] | |
76 | 77 | |
77 | - @ldapData[kind][:external] = @ldapData[kind][:internal].map do |data| | |
78 | - map = { :dn => :id } | |
79 | - map.merge!(LDAP_MAP[kind]) if LDAP_MAP[kind] | |
78 | + @ldapData[kind][:external] = @ldapData[kind][:internal].map do |data| | |
79 | + map = { :dn => :id } | |
80 | + map.merge!(LDAP_MAP[kind]) if LDAP_MAP[kind] | |
80 | 81 | |
81 | - ydata = {} | |
82 | - data.each do |key,value| | |
83 | - ydata.merge!({ map[key] || key => value.size==1?value[0]:value.to_a }) | |
84 | - end | |
85 | - ydata | |
86 | - end if ! @ldapData[kind][:external] | |
82 | + ydata = {} | |
83 | + data.each do |key,value| | |
84 | + ydata.merge!({ map[key] || key => value.size==1?value[0]:value.to_a }) | |
85 | + end | |
86 | + ydata | |
87 | + end if ! @ldapData[kind][:external] | |
87 | 88 | |
88 | - @ldapData[kind][:external].each{|ydata| yield ydata} | |
89 | + @ldapData[kind][:external].each{|ydata| yield ydata} | |
89 | 90 | end |
90 | 91 | |
91 | 92 | def update(kind, data) |
92 | 93 | map = {} |
93 | 94 | map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind] |
94 | 95 | |
95 | - entry = Net::LDAP::Entry.new(data[:id]) | |
96 | - | |
97 | 96 | odata = @ldapData[kind][:external].find{|edata| edata[:id] == data[:id]} |
97 | + | |
98 | + data.each do |key,value| | |
99 | + pat_key = map[key] ? map[key] : key | |
100 | + if odata[:id] =~ /(^|, *)#{pat_key.to_s}=([^, ]+)/ && $2 != value | |
101 | + return replace(kind, data) | |
102 | + end | |
103 | + end | |
104 | + | |
105 | + entry = Net::LDAP::Entry.new(data[:id]) | |
98 | 106 | data = data.find_all{|key,value| value != odata[key]} |
99 | 107 | data.delete(:id) |
100 | 108 | |
... | ... | @@ -105,17 +113,52 @@ class SystemDataBackendLdap |
105 | 113 | entry[key] = value |
106 | 114 | end |
107 | 115 | |
108 | - if not replace.empty? | |
116 | + if replace.empty? | |
117 | + puts 'INFO: no changes' | |
118 | + else | |
109 | 119 | entry[:changetype] = 'modify' |
110 | 120 | entry[:replace] = replace |
111 | 121 | LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind] |
112 | 122 | |
113 | 123 | puts entry.to_ldif |
114 | - else | |
115 | - puts 'INFO: no changes' | |
116 | 124 | end |
117 | 125 | end |
118 | 126 | |
127 | + def replace(kind, data) | |
128 | + puts 'INFO: do replace' | |
129 | + puts '----------------' | |
130 | + odata = @ldapData[kind][:external].find{|edata| edata[:id] == data[:id]} | |
131 | + delete(odata) | |
132 | + puts | |
133 | + insert(kind, data) | |
134 | + puts '----------------' | |
135 | + end | |
136 | + | |
137 | + def delete(data) | |
138 | + entry = Net::LDAP::Entry.new(data[:id]) | |
139 | + entry[:changetype] = 'delete' | |
140 | + | |
141 | + puts entry.to_ldif | |
142 | + end | |
143 | + | |
144 | + def insert(kind, data) | |
145 | + map = {} | |
146 | + map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind] | |
147 | + | |
148 | + data.delete(:id) | |
149 | + entry = Net::LDAP::Entry.new(ldapDn(kind, data)) | |
150 | + entry[:changetype] = 'add' | |
151 | + entry[:objectclass] = LDAP_OBJECTCLASS[kind] | |
152 | + | |
153 | + data.each do |key,value| | |
154 | + key = map[key] if map[key] | |
155 | + entry[key] = value | |
156 | + end | |
157 | + LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind] | |
158 | + | |
159 | + puts entry.to_ldif | |
160 | + end | |
161 | + | |
119 | 162 | private |
120 | 163 | |
121 | 164 | def ldapBase(kind) |
... | ... | @@ -125,4 +168,17 @@ class SystemDataBackendLdap |
125 | 168 | end |
126 | 169 | end |
127 | 170 | |
171 | + def ldapDn(kind, data) | |
172 | + case(kind) | |
173 | + when :User | |
174 | + "uid=#{data[:name]},ou=user,#{ldapBase(kind)}" | |
175 | + when :Group | |
176 | + "cn=#{data[:name]},ou=group,#{ldapBase(kind)}" | |
177 | + when :Site | |
178 | + "o=#{data[:name]},#{ldapBase(kind)}" | |
179 | + else | |
180 | + "not yet implemented" | |
181 | + end | |
182 | + end | |
183 | + | |
128 | 184 | end | ... | ... |
Please
register
or
login
to post a comment