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 | end | 90 | end |
| 90 | 91 | ||
| 91 | def update(kind, data) | 92 | def update(kind, data) |
| 92 | map = {} | 93 | map = {} |
| 93 | map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind] | 94 | map.merge!(LDAP_MAP[kind].invert) if LDAP_MAP[kind] |
| 94 | 95 | ||
| 95 | - entry = Net::LDAP::Entry.new(data[:id]) | ||
| 96 | - | ||
| 97 | odata = @ldapData[kind][:external].find{|edata| edata[:id] == data[:id]} | 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 | data = data.find_all{|key,value| value != odata[key]} | 106 | data = data.find_all{|key,value| value != odata[key]} |
| 99 | data.delete(:id) | 107 | data.delete(:id) |
| 100 | 108 | ||
| @@ -105,17 +113,52 @@ class SystemDataBackendLdap | @@ -105,17 +113,52 @@ class SystemDataBackendLdap | ||
| 105 | entry[key] = value | 113 | entry[key] = value |
| 106 | end | 114 | end |
| 107 | 115 | ||
| 108 | - if not replace.empty? | 116 | + if replace.empty? |
| 117 | + puts 'INFO: no changes' | ||
| 118 | + else | ||
| 109 | entry[:changetype] = 'modify' | 119 | entry[:changetype] = 'modify' |
| 110 | entry[:replace] = replace | 120 | entry[:replace] = replace |
| 111 | LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind] | 121 | LDAP_LAMBDA[kind].call(entry) if LDAP_LAMBDA[kind] |
| 112 | 122 | ||
| 113 | puts entry.to_ldif | 123 | puts entry.to_ldif |
| 114 | - else | ||
| 115 | - puts 'INFO: no changes' | ||
| 116 | end | 124 | end |
| 117 | end | 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 | private | 162 | private |
| 120 | 163 | ||
| 121 | def ldapBase(kind) | 164 | def ldapBase(kind) |
| @@ -125,4 +168,17 @@ class SystemDataBackendLdap | @@ -125,4 +168,17 @@ class SystemDataBackendLdap | ||
| 125 | end | 168 | end |
| 126 | end | 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 | end | 184 | end |
Please
register
or
login
to post a comment