Commit 56b9c94ac19670c1d00374cbe7cb631b95d654c8

Authored by Georg GH. Hopp
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