1 |
diff -ruN e-smith-ldap-5.2.0.ldap-init/root/etc/e-smith/events/actions/ldap-update e-smith-ldap-5.2.0/root/etc/e-smith/events/actions/ldap-update |
2 |
--- e-smith-ldap-5.2.0.ldap-init/root/etc/e-smith/events/actions/ldap-update 2010-12-01 11:12:30.000000000 -0700 |
3 |
+++ e-smith-ldap-5.2.0/root/etc/e-smith/events/actions/ldap-update 2010-12-01 12:08:29.000000000 -0700 |
4 |
@@ -1,4 +1,4 @@ |
5 |
-#!/usr/bin/perl -w |
6 |
+#!/bin/bash |
7 |
|
8 |
#---------------------------------------------------------------------- |
9 |
# copyright (C) 1999, 2000 e-smith, inc. |
10 |
@@ -22,456 +22,4 @@ |
11 |
# call us on 1 888 ESMITH 1 (US/Canada toll free) or +1 613 564 8000 |
12 |
#---------------------------------------------------------------------- |
13 |
|
14 |
-package esmith; |
15 |
- |
16 |
-use strict; |
17 |
-use Errno; |
18 |
-use esmith::ConfigDB; |
19 |
-use esmith::AccountsDB; |
20 |
-use esmith::util; |
21 |
-use Net::LDAP; |
22 |
-use Date::Parse; |
23 |
- |
24 |
-my $c = esmith::ConfigDB->open_ro; |
25 |
-my $a = esmith::AccountsDB->open_ro; |
26 |
- |
27 |
-my $l = $c->get('ldap'); |
28 |
-my $status = $l->prop('status') || "disabled"; |
29 |
-unless ($status eq "enabled" ) |
30 |
-{ |
31 |
- warn "Not running action script $0, LDAP service not enabled!\n"; |
32 |
- exit(0); |
33 |
-} |
34 |
- |
35 |
-my $hostname = $c->get('SystemName') |
36 |
- || die("Couldn't determine system name"); |
37 |
-$hostname = $hostname->value; |
38 |
- |
39 |
-my $domain = $c->get('DomainName') |
40 |
- || die("Couldn't determine domain name"); |
41 |
-$domain = $domain->value; |
42 |
- |
43 |
-my $schema = '/etc/openldap/schema/samba.schema'; |
44 |
-my $map = { 'FirstName' => 'givenName', |
45 |
- 'LastName' => 'sn', |
46 |
- 'Phone' => 'telephoneNumber', |
47 |
- 'Company' => 'o', |
48 |
- 'Dept' => 'ou', |
49 |
- 'City' => 'l', |
50 |
- 'Street' => 'street', |
51 |
- }; |
52 |
- |
53 |
-my @accounts; |
54 |
-my $account; |
55 |
-my $event = shift || die "Event name must be specified"; |
56 |
-if ($event eq 'ldap-update' or $event eq 'bootstrap-ldap-save') |
57 |
-{ |
58 |
- @accounts = ($a->users, $a->groups, $a->ibays, $a->get_all_by_prop(type => 'machine')); |
59 |
- push(@accounts, $a->get('admin')); |
60 |
-} |
61 |
-else |
62 |
-{ |
63 |
- my @name = @ARGV; |
64 |
- die "Account name argument missing." unless scalar (@name) >= 1; |
65 |
- |
66 |
- foreach my $name (@name) |
67 |
- { |
68 |
- $account = $a->get($name); |
69 |
- die "Account $name not found.\n" unless defined $account; |
70 |
- my $type = $account->prop('type') || "unknown"; |
71 |
- |
72 |
- die "Account $name is not a user, group, ibay, machine account; update LDAP entry failed.\n" |
73 |
- unless ($type =~ m{^(?:user|group|ibay|machine)$} or $name eq 'admin'); |
74 |
- push @accounts, $account; |
75 |
- } |
76 |
-} |
77 |
- |
78 |
-#------------------------------------------------------------ |
79 |
-# Read all samba groups (can't do individual lookups) |
80 |
-#------------------------------------------------------------ |
81 |
- |
82 |
-my $groupmap = (); |
83 |
- |
84 |
-# Only do if schema is found |
85 |
-if ( -f "$schema" and -x '/usr/bin/net' ) |
86 |
-{ |
87 |
- foreach (`/usr/bin/net groupmap list 2> /dev/null`){ |
88 |
- chomp; |
89 |
- next if m{\(S-1-5-32-\d+\)}; |
90 |
- $groupmap->{$3} = { name => "$1", sid => "$2" } if (/^(.*) \((S-.*-\d+)\) -> (.*)$/); |
91 |
- } |
92 |
-} |
93 |
- |
94 |
-#------------------------------------------------------------ |
95 |
-# Update LDAP database entry. |
96 |
-#------------------------------------------------------------ |
97 |
-my $base = esmith::util::ldapBase ($domain); |
98 |
-my $pw = esmith::util::LdapPassword(); |
99 |
- |
100 |
-my $ldap = Net::LDAP->new('localhost') |
101 |
- or die "$@"; |
102 |
- |
103 |
-$ldap->bind( |
104 |
- dn => "cn=root,$base", |
105 |
- password => $pw |
106 |
-); |
107 |
- |
108 |
-my ($dc,undef) = split (/\./, $domain); |
109 |
-my $o = $l->prop('defaultCompany') || $domain; |
110 |
- |
111 |
-# Try and find base record |
112 |
-my $seen; |
113 |
-my @objects = qw(top organization dcObject); |
114 |
-my $result = $ldap->search( base => $base, filter => '(objectClass=*)', scope => 'base' ); |
115 |
-if ($result->code == 32) |
116 |
-{ |
117 |
- $result = $ldap->add( $base, attr => [ dc => $dc, o => $o, objectClass => \@objects ] ); |
118 |
-} |
119 |
-elsif ($result->code) |
120 |
-{ |
121 |
- warn "failed checking base entry $base: ", $result->error; |
122 |
-} |
123 |
-else |
124 |
-{ |
125 |
- # Don't overwrite objectClass (just update if necessary) |
126 |
- $seen = (); |
127 |
- @objects = grep { ! $seen->{$_} ++ } (@objects, $result->entry(0)->get_value('objectClass') ); |
128 |
- $ldap->modify( $base, replace => { dc => $dc, o => $o, objectClass => \@objects } ); |
129 |
-} |
130 |
-warn "failed to add/update entry $base: ", $result->error if $result->code; |
131 |
- |
132 |
-# Try and find container records |
133 |
-foreach my $obj ( qw(Users Groups Computers) ) |
134 |
-{ |
135 |
- @objects = qw(top organizationalUnit); |
136 |
- $result = $ldap->search( base => "ou=$obj,$base", filter => '(objectClass=*)', scope => 'base' ); |
137 |
- if ($result->code == 32) |
138 |
- { |
139 |
- $result = $ldap->add( "ou=$obj,$base", attr => [ ou => $obj, objectClass => \@objects ] ); |
140 |
- } |
141 |
- elsif ($result->code) |
142 |
- { |
143 |
- warn "failed checking base entry ou=$obj,$base: ", $result->error; |
144 |
- } |
145 |
- else |
146 |
- { |
147 |
- # Don't overwrite objectClass (just update if necessary) |
148 |
- $seen = (); |
149 |
- @objects = grep { ! $seen->{$_} ++ } (@objects, $result->entry(0)->get_value('objectClass') ); |
150 |
- $result = $ldap->modify( "ou=$obj,$base", replace => { ou => $obj, objectClass => \@objects } ); |
151 |
- } |
152 |
- warn "failed to add/update entry ou=$obj,$base: ", $result->error if $result->code; |
153 |
-} |
154 |
- |
155 |
-my $updates; |
156 |
- |
157 |
-#------------------------------------------------------------ |
158 |
-# Ensure nobody, shared, www objects are there |
159 |
-#------------------------------------------------------------ |
160 |
-foreach my $user (qw/www/){ |
161 |
- my $dn = "uid=$user,ou=Users,$base"; |
162 |
- utf8::upgrade($dn); |
163 |
- $updates->{$dn}->{objectClass} = ['account', 'posixAccount', 'shadowAccount']; |
164 |
- |
165 |
- # Read information from getent passwd |
166 |
- @{$updates->{$dn}}{'uid','userPassword','uidNumber','gidNumber','junk','junk','gecos','homeDirectory','loginShell'} = getpwnam($user); |
167 |
- $updates->{$dn}->{userPassword} = "!*" if $updates->{$dn}->{userPassword} eq '!!'; |
168 |
- $updates->{$dn}->{userPassword} =~ s/^/{CRYPT}/ unless $updates->{$dn}->{userPassword} =~ m/^{/; |
169 |
- $updates->{$dn}->{cn} = $updates->{$dn}->{gecos}; |
170 |
- |
171 |
- # Samba parameters if we find the samba.schema |
172 |
- if ( -f "$schema" and -x '/usr/bin/pdbedit' ) |
173 |
- { |
174 |
- my $line = `/usr/bin/pdbedit -wu '$user' 2> /dev/null`; |
175 |
- chomp($line); |
176 |
- if ($line) |
177 |
- { |
178 |
- @{$updates->{$dn}}{'junk','junk','sambaLMPassword','sambaNTPassword'} = split(/:/,$line); |
179 |
- foreach $line (`/usr/bin/pdbedit -vu '$user' 2> /dev/null`) |
180 |
- { |
181 |
- chomp($line); |
182 |
- $updates->{$dn}->{sambaSID} = $1 if $line =~ m{User SID:\s+(S-.*)$}; |
183 |
- $updates->{$dn}->{displayName} = $1 if $line =~ m{Full Name:\s+(.*)$}; |
184 |
- $updates->{$dn}->{sambaPrimaryGroupSID} = $1 if $line =~ m{Primary Group SID:\s+(S-.*)$}; |
185 |
- $updates->{$dn}->{sambaAcctFlags} = $1 if $line =~ m{Account Flags:\s+(.*)$}; |
186 |
- $updates->{$dn}->{sambaPwdLastSet} = str2time($1) if $line =~ m{Password last set:\s+(.*)$}; |
187 |
- } |
188 |
- push @{$updates->{$dn}->{objectClass}}, 'sambaSamAccount'; |
189 |
- } |
190 |
- else |
191 |
- { |
192 |
- $updates->{$dn}->{sambaLMPassword} = []; |
193 |
- $updates->{$dn}->{sambaNTPassword} = []; |
194 |
- $updates->{$dn}->{sambaSID} = []; |
195 |
- $updates->{$dn}->{displayName} = []; |
196 |
- $updates->{$dn}->{sambaPrimaryGroupSID} = []; |
197 |
- $updates->{$dn}->{sambaAcctFlags} = []; |
198 |
- $updates->{$dn}->{sambaPwdLastSet} = []; |
199 |
- } |
200 |
- } |
201 |
-} |
202 |
-endpwent(); |
203 |
- |
204 |
-foreach my $group (qw/nobody shared www/){ |
205 |
- my $dn = "cn=$group,ou=Groups,$base"; |
206 |
- utf8::upgrade($dn); |
207 |
- $updates->{$dn}->{objectClass} = ['posixGroup']; |
208 |
- |
209 |
- # Read information from getent group |
210 |
- @{$updates->{$dn}}{'cn','junk','gidNumber','memberUid'} = getgrnam($group); |
211 |
- $updates->{$dn}->{memberUid} = [ split /\s+/, $updates->{$dn}->{memberUid} ]; |
212 |
- |
213 |
- # Ensure groups have the needed properties |
214 |
- if ($group eq 'shared'){ |
215 |
- push @{$updates->{$dn}->{objectClass}}, 'mailboxRelatedObject'; |
216 |
- $updates->{$dn}->{mail} = "everyone\@$domain"; |
217 |
- } |
218 |
- |
219 |
- # Samba parameters if we find the samba.schema |
220 |
- if ( -f "$schema" ) |
221 |
- { |
222 |
- if ( exists $groupmap->{$group} ) |
223 |
- { |
224 |
- push @{$updates->{$dn}->{objectClass}}, 'sambaGroupMapping'; |
225 |
- $updates->{$dn}->{displayName} = $groupmap->{$group}->{name}; |
226 |
- $updates->{$dn}->{sambaSID} = $groupmap->{$group}->{sid}; |
227 |
- $updates->{$dn}->{sambaGroupType} = '2'; |
228 |
- } |
229 |
- else |
230 |
- { |
231 |
- $updates->{$dn}->{displayName} = []; |
232 |
- $updates->{$dn}->{sambaSID} = []; |
233 |
- $updates->{$dn}->{sambaGroupType} = []; |
234 |
- } |
235 |
- } |
236 |
-} |
237 |
-endgrent(); |
238 |
- |
239 |
-#------------------------------------------------------------ |
240 |
-# Create a list of updates that need to happen |
241 |
-#------------------------------------------------------------ |
242 |
-foreach my $acct (@accounts) |
243 |
-{ |
244 |
- my $key = $acct->key; |
245 |
- my $type = $acct->prop('type'); |
246 |
- my $desc = undef; |
247 |
- my $dn; |
248 |
- |
249 |
- if ($type =~ m{^(?:user|group|ibay|machine)$} or $key eq 'admin') |
250 |
- { |
251 |
- #------------------------------------------------------------ |
252 |
- # Do the user portion |
253 |
- #------------------------------------------------------------ |
254 |
- if ($type eq 'machine') |
255 |
- { |
256 |
- $dn = "uid=$key,ou=Computers,$base"; |
257 |
- } |
258 |
- else |
259 |
- { |
260 |
- $dn = "uid=$key,ou=Users,$base"; |
261 |
- } |
262 |
- utf8::upgrade($dn); |
263 |
- $updates->{$dn}->{objectClass} = ['posixAccount', 'shadowAccount']; |
264 |
- |
265 |
- # Read information from getent passwd |
266 |
- @{$updates->{$dn}}{'uid','userPassword','uidNumber','gidNumber','junk','junk','gecos','homeDirectory','loginShell'} = getpwnam($key); |
267 |
- unless ($updates->{$dn}->{uid}) |
268 |
- { |
269 |
- delete $updates->{$dn}; |
270 |
- next; |
271 |
- } |
272 |
- $updates->{$dn}->{userPassword} = "!*" if $updates->{$dn}->{userPassword} eq '!!'; |
273 |
- $updates->{$dn}->{userPassword} =~ s/^/{CRYPT}/ unless $updates->{$dn}->{userPassword} =~ m/^{/; |
274 |
- $desc = $updates->{$dn}->{cn} = $updates->{$dn}->{gecos}; |
275 |
- |
276 |
- # Load values from db record |
277 |
- foreach my $attr ( keys %$map ) |
278 |
- { |
279 |
- my $val = $acct->prop($attr); |
280 |
- $updates->{$dn}->{$map->{$attr}} = $val if defined $val; |
281 |
- } |
282 |
- |
283 |
- # Ensure users have the needed properties |
284 |
- if ($type eq 'user' or $key eq 'admin') |
285 |
- { |
286 |
- push @{$updates->{$dn}->{objectClass}}, 'inetOrgPerson'; |
287 |
- $updates->{$dn}->{mail} = "$key\@$domain"; |
288 |
- } |
289 |
- else |
290 |
- { |
291 |
- push @{$updates->{$dn}->{objectClass}}, 'account'; |
292 |
- } |
293 |
- |
294 |
- # Samba parameters if we find the samba.schema |
295 |
- if ( -f "$schema" and -x '/usr/bin/pdbedit' ) |
296 |
- { |
297 |
- my $line = `/usr/bin/pdbedit -wu '$key' 2> /dev/null`; |
298 |
- chomp($line); |
299 |
- if ($line) |
300 |
- { |
301 |
- @{$updates->{$dn}}{'junk','junk','sambaLMPassword','sambaNTPassword'} = split(/:/,$line); |
302 |
- foreach $line (`/usr/bin/pdbedit -vu '$key' 2> /dev/null`) |
303 |
- { |
304 |
- chomp($line); |
305 |
- $updates->{$dn}->{sambaSID} = $1 if $line =~ m{User SID:\s+(S-.*)$}; |
306 |
- $updates->{$dn}->{displayName} = $1 if $line =~ m{Full Name:\s+(.*)$}; |
307 |
- $updates->{$dn}->{sambaPrimaryGroupSID} = $1 if $line =~ m{Primary Group SID:\s+(S-.*)$}; |
308 |
- $updates->{$dn}->{sambaAcctFlags} = $1 if $line =~ m{Account Flags:\s+(.*)$}; |
309 |
- $updates->{$dn}->{sambaPwdLastSet} = str2time($1) if $line =~ m{Password last set:\s+(.*)$}; |
310 |
- } |
311 |
- push @{$updates->{$dn}->{objectClass}}, 'sambaSamAccount'; |
312 |
- } |
313 |
- else |
314 |
- { |
315 |
- $updates->{$dn}->{sambaLMPassword} = []; |
316 |
- $updates->{$dn}->{sambaNTPassword} = []; |
317 |
- $updates->{$dn}->{sambaSID} = []; |
318 |
- $updates->{$dn}->{displayName} = []; |
319 |
- $updates->{$dn}->{sambaPrimaryGroupSID} = []; |
320 |
- $updates->{$dn}->{sambaAcctFlags} = []; |
321 |
- $updates->{$dn}->{sambaPwdLastSet} = []; |
322 |
- } |
323 |
- } |
324 |
- |
325 |
- #------------------------------------------------------------ |
326 |
- # Do the group portion |
327 |
- #------------------------------------------------------------ |
328 |
- $dn = "cn=$key,ou=Groups,$base"; |
329 |
- utf8::upgrade($dn); |
330 |
- $updates->{$dn}->{objectClass} = ['posixGroup']; |
331 |
- |
332 |
- # Read information from getent group |
333 |
- @{$updates->{$dn}}{'cn','junk','gidNumber','memberUid'} = getgrnam($key); |
334 |
- $updates->{$dn}->{memberUid} = [ split /\s+/, $updates->{$dn}->{memberUid} ]; |
335 |
- |
336 |
- # Ensure groups have the needed properties |
337 |
- if ($type eq 'group') |
338 |
- { |
339 |
- push @{$updates->{$dn}->{objectClass}}, 'mailboxRelatedObject'; |
340 |
- $updates->{$dn}->{mail} = "$key\@$domain"; |
341 |
- $updates->{$dn}->{description} = $desc if $desc; |
342 |
- } |
343 |
- |
344 |
- # Samba parameters if we find the samba.schema |
345 |
- if ( -f "$schema" ) |
346 |
- { |
347 |
- if ( exists $groupmap->{$key} ) |
348 |
- { |
349 |
- push @{$updates->{$dn}->{objectClass}}, 'sambaGroupMapping'; |
350 |
- $updates->{$dn}->{displayName} = $groupmap->{$key}->{name}; |
351 |
- $updates->{$dn}->{sambaSID} = $groupmap->{$key}->{sid}; |
352 |
- $updates->{$dn}->{sambaGroupType} = '2'; |
353 |
- } |
354 |
- else |
355 |
- { |
356 |
- $updates->{$dn}->{displayName} = []; |
357 |
- $updates->{$dn}->{sambaSID} = []; |
358 |
- $updates->{$dn}->{sambaGroupType} = []; |
359 |
- } |
360 |
- } |
361 |
- } |
362 |
-} |
363 |
-endpwent(); |
364 |
-endgrent(); |
365 |
- |
366 |
-#------------------------------------------------------------ |
367 |
-# Update LDAP database entry. |
368 |
-#------------------------------------------------------------ |
369 |
-foreach my $dn (keys %$updates) |
370 |
-{ |
371 |
- # Try and find record |
372 |
- $result = $ldap->search( base => $dn, filter => '(objectClass=*)', scope => 'base' ); |
373 |
- warn "failed looking up entry $dn: ", $result->error if $result->code && $result->code != 32; |
374 |
- my $code = $result->code; |
375 |
- my @objectClass = $code == 32 ? () : $result->entry(0)->get_value('objectClass'); |
376 |
- |
377 |
- # Clean up attributes and convert to utf8 |
378 |
- delete $updates->{$dn}->{'junk'}; |
379 |
- foreach my $attr ( keys %{$updates->{$dn}} ) |
380 |
- { |
381 |
- if ( ref($updates->{$dn}->{$attr}) eq 'ARRAY' ) |
382 |
- { |
383 |
- if ( $code == 32 and scalar(@{$updates->{$dn}->{$attr}}) == 0 ) |
384 |
- { |
385 |
- delete $updates->{$dn}->{$attr}; |
386 |
- } |
387 |
- else |
388 |
- { |
389 |
- for (my $c = 0; $c < scalar(@{$updates->{$dn}->{$attr}}); $c++) |
390 |
- { |
391 |
- utf8::upgrade($updates->{$dn}->{$attr}[$c]); |
392 |
- } |
393 |
- } |
394 |
- } |
395 |
- else |
396 |
- { |
397 |
- if ($updates->{$dn}->{$attr} !~ /^\s*$/) |
398 |
- { |
399 |
- utf8::upgrade($updates->{$dn}->{$attr}); |
400 |
- } |
401 |
- elsif ( $code == 32 ) |
402 |
- { |
403 |
- delete $updates->{$dn}->{$attr}; |
404 |
- } |
405 |
- else |
406 |
- { |
407 |
- $updates->{$dn}->{$attr} = []; |
408 |
- } |
409 |
- } |
410 |
- } |
411 |
- |
412 |
- # Try and find old record (sme7) |
413 |
- my ($oldfilter, undef, $oldsearchbase) = split /,/, $dn, 3; |
414 |
- my $oldresult = $ldap->search( base => "$oldfilter,$oldsearchbase", filter => '(objectClass=*)', scope => 'base' ); |
415 |
- if ($oldresult->code) |
416 |
- { |
417 |
- warn "failed looking up old entry $oldfilter,$oldsearchbase: ", $result->error if $oldresult->code != 32; |
418 |
- } |
419 |
- else |
420 |
- { |
421 |
- if ($code == 32) |
422 |
- { |
423 |
- my ($newdn, $newbase) = split /,/, $dn, 2; |
424 |
- |
425 |
- # Ensure key entry exist in old record before renaming |
426 |
- $result = $ldap->modify( "$oldfilter,$oldsearchbase", replace => { split('=', $newdn) } ); |
427 |
- warn "failed to add attributes to old entry $oldfilter,$oldsearchbase: ", $result->error if $result->code; |
428 |
- |
429 |
- # Move old record to new location |
430 |
- $result = $ldap->moddn( "$oldfilter,$oldsearchbase", newrdn => $newdn, newsuperior => $newbase, deleteoldrdn => 1 ); |
431 |
- warn "failed to rename old entry $oldfilter,$oldsearchbase: ", $result->error if $result->code; |
432 |
- |
433 |
- # Set things up as if we had found the new entry |
434 |
- $code = $oldresult->code; |
435 |
- @objectClass = $oldresult->entry(0)->get_value('objectClass'); |
436 |
- } |
437 |
- else |
438 |
- { |
439 |
- $result = $ldap->delete( "$oldfilter,$oldsearchbase" ); |
440 |
- warn "failed to remove old entry $oldfilter,$oldsearchbase: ", $result->error if $result->code; |
441 |
- } |
442 |
- } |
443 |
- |
444 |
- # Perform insert or update |
445 |
- if ( $code == 32 ) |
446 |
- { |
447 |
- $result = $ldap->add( $dn, attrs => [ %{$updates->{$dn}} ] ); |
448 |
- $result->code && warn "failed to add entry $dn: ", $result->error; |
449 |
- } |
450 |
- else |
451 |
- { |
452 |
- # Don't overwrite objectClass (just remove person if existing) |
453 |
- $seen = { person => 1 }; |
454 |
- |
455 |
- # Remove samba objectClasses if removing samba attributes |
456 |
- @{$seen}{'sambaSamAccount','sambaGroupMapping'} = (1,1) if ref($updates->{$dn}->{sambaSID}) eq 'ARRAY'; |
457 |
- |
458 |
- @{$updates->{$dn}->{objectClass}} = grep { ! $seen->{$_}++ } (@{$updates->{$dn}->{objectClass}}, @objectClass ); |
459 |
- |
460 |
- $result = $ldap->modify( $dn, replace => $updates->{$dn}); |
461 |
- $result->code && warn "failed to modify entry $dn: ", $result->error; |
462 |
- } |
463 |
-} |
464 |
-$ldap->unbind; |
465 |
- |
466 |
-exit (0); |
467 |
+/var/service/ldap/ldif-fix --update |
468 |
diff -ruN e-smith-ldap-5.2.0.ldap-init/root/etc/e-smith/templates/home/e-smith/db/ldap/ldif/20ldif e-smith-ldap-5.2.0/root/etc/e-smith/templates/home/e-smith/db/ldap/ldif/20ldif |
469 |
--- e-smith-ldap-5.2.0.ldap-init/root/etc/e-smith/templates/home/e-smith/db/ldap/ldif/20ldif 2010-12-01 11:12:30.000000000 -0700 |
470 |
+++ e-smith-ldap-5.2.0/root/etc/e-smith/templates/home/e-smith/db/ldap/ldif/20ldif 1969-12-31 17:00:00.000000000 -0700 |
471 |
@@ -1,20 +0,0 @@ |
472 |
-{ |
473 |
- foreach my $dn (keys %$ldif) |
474 |
- { |
475 |
- delete $ldif->{$dn}->{'junk'}; |
476 |
- $OUT .= "dn: $dn\n"; |
477 |
- foreach my $attr ( keys %{$ldif->{$dn}} ) |
478 |
- { |
479 |
- if (ref($ldif->{$dn}->{$attr}) eq 'ARRAY') |
480 |
- { |
481 |
- my %seen = (); |
482 |
- $OUT .= "$attr: $_\n" foreach grep { ! $seen{$_}++ } @{$ldif->{$dn}->{$attr}}; |
483 |
- } |
484 |
- else |
485 |
- { |
486 |
- $OUT .= "$attr: ".$ldif->{$dn}->{$attr}."\n" if $ldif->{$dn}->{$attr}; |
487 |
- } |
488 |
- } |
489 |
- $OUT .= "\n"; |
490 |
- } |
491 |
-} |
492 |
diff -ruN e-smith-ldap-5.2.0.ldap-init/root/etc/e-smith/templates/home/e-smith/db/ldap/ldif/template-begin e-smith-ldap-5.2.0/root/etc/e-smith/templates/home/e-smith/db/ldap/ldif/template-begin |
493 |
--- e-smith-ldap-5.2.0.ldap-init/root/etc/e-smith/templates/home/e-smith/db/ldap/ldif/template-begin 2010-12-01 11:12:30.000000000 -0700 |
494 |
+++ e-smith-ldap-5.2.0/root/etc/e-smith/templates/home/e-smith/db/ldap/ldif/template-begin 1969-12-31 17:00:00.000000000 -0700 |
495 |
@@ -1,207 +0,0 @@ |
496 |
-{ |
497 |
- use esmith::AccountsDB; |
498 |
- use esmith::util; |
499 |
- use Date::Parse; |
500 |
- |
501 |
- my $schema = '/etc/openldap/schema/samba.schema'; |
502 |
- |
503 |
- $a = esmith::AccountsDB->open_ro; |
504 |
- $ldapBase = esmith::util::ldapBase ($DomainName); |
505 |
- |
506 |
- local ($dn, $dc, $obj, $attr, $account, $type); |
507 |
- ($dc) = split (/\./, $DomainName); |
508 |
- |
509 |
- $ldif = (); |
510 |
- |
511 |
- # Top domain object |
512 |
- utf8::upgrade($ldapBase); |
513 |
- $ldif->{$ldapBase}->{objectClass} = [ qw(top organization dcObject) ]; |
514 |
- $ldif->{$ldapBase}->{dc} = $dc; |
515 |
- $ldif->{$ldapBase}->{o} = $ldap{defaultCompany} || $DomainName; |
516 |
- |
517 |
- # Top level groups |
518 |
- foreach $obj ( qw(Users Groups Computers) ) |
519 |
- { |
520 |
- $dn = "ou=$obj,$ldapBase"; |
521 |
- utf8::upgrade($dn); |
522 |
- |
523 |
- $ldif->{$dn}->{objectClass} = [ qw(top organizationalUnit) ]; |
524 |
- $ldif->{$dn}->{ou} = $obj; |
525 |
- } |
526 |
- |
527 |
- local $dnmap = (); |
528 |
- |
529 |
- # Read in user details |
530 |
- while(my ($key,$pwd,$uid,$gid,undef,undef,$gecos,$dir,$shell) = getpwent()) |
531 |
- { |
532 |
- # skip non sme users |
533 |
- $account = $a->get($key) || next; |
534 |
- $type = $account->prop('type') || 'unknown'; |
535 |
- next unless ($type =~ m{^(?:user|group|ibay|machine)$} or $key eq 'admin'); |
536 |
- |
537 |
- if ($type eq 'machine') |
538 |
- { |
539 |
- $dn = "uid=$key,ou=Computers,$ldapBase"; |
540 |
- utf8::upgrade($dn); |
541 |
- } |
542 |
- else |
543 |
- { |
544 |
- $dn = "uid=$key,ou=Users,$ldapBase"; |
545 |
- utf8::upgrade($dn); |
546 |
- } |
547 |
- |
548 |
- $dnmap->{$key}->{user} = $dn; |
549 |
- |
550 |
- $ldif->{$dn}->{objectClass} = [ qw(posixAccount shadowAccount) ]; |
551 |
- $ldif->{$dn}->{uid} = $key; |
552 |
- $pwd = "!*" if $pwd eq '!!'; |
553 |
- $ldif->{$dn}->{userPassword} = ($pwd =~ m/^\{/) ? $pwd : "\{CRYPT\}$pwd"; |
554 |
- $ldif->{$dn}->{uidNumber} = $uid; |
555 |
- $ldif->{$dn}->{gidNumber} = $gid; |
556 |
- $ldif->{$dn}->{gecos} = $gecos || ''; |
557 |
- $ldif->{$dn}->{cn} = $gecos || ''; |
558 |
- $ldif->{$dn}->{homeDirectory} = $dir; |
559 |
- $ldif->{$dn}->{loginShell} = $shell; |
560 |
- |
561 |
- if ($type eq 'user' or $key eq 'admin') |
562 |
- { |
563 |
- push @{$ldif->{$dn}->{objectClass}}, 'inetOrgPerson'; |
564 |
- $ldif->{$dn}->{mail} = "$key\@$DomainName"; |
565 |
- $ldif->{$dn}->{givenName} = $account->prop('FirstName') || ''; |
566 |
- $ldif->{$dn}->{sn} = $account->prop('LastName') || ''; |
567 |
- $ldif->{$dn}->{telephoneNumber} = $account->prop('Phone') || ''; |
568 |
- $ldif->{$dn}->{o} = $account->prop('Company') || ''; |
569 |
- $ldif->{$dn}->{ou} = $account->prop('Dept') || ''; |
570 |
- $ldif->{$dn}->{l} = $account->prop('City') || ''; |
571 |
- $ldif->{$dn}->{street} = $account->prop('Street') || ''; |
572 |
- } |
573 |
- else |
574 |
- { |
575 |
- push @{$ldif->{$dn}->{objectClass}}, 'account'; |
576 |
- } |
577 |
- } |
578 |
- endpwent(); |
579 |
- |
580 |
- # www is a special user for all accounts |
581 |
- foreach my $user (qw/www/) |
582 |
- { |
583 |
- $dn = "uid=$user,ou=Users,$ldapBase"; |
584 |
- utf8::upgrade($dn); |
585 |
- |
586 |
- $dnmap->{$user}->{user} = $dn; |
587 |
- |
588 |
- $ldif->{$dn}->{objectClass} = [ qw(account posixAccount shadowAccount) ]; |
589 |
- @{$ldif->{$dn}}{'uid','userPassword','uidNumber','gidNumber','junk','junk','gecos','homeDirectory','loginShell'} = getpwnam($user); |
590 |
- $ldif->{$dn}->{userPassword} = "!*" if $ldif->{$dn}->{userPassword} eq '!!'; |
591 |
- $ldif->{$dn}->{userPassword} =~ s/^/{CRYPT}/ unless $ldif->{$dn}->{userPassword} =~ m/^\{/; |
592 |
- $ldif->{$dn}->{cn} = $ldif->{$dn}->{gecos} || ''; |
593 |
- } |
594 |
- endpwent(); |
595 |
- |
596 |
- # Read in group details |
597 |
- while(my ($key,undef,$gid,$members) = getgrent()) |
598 |
- { |
599 |
- # skip non sme groups |
600 |
- $account = $a->get($key) || next; |
601 |
- $type = $account->prop('type') || 'unknown'; |
602 |
- next unless ($type =~ m{^(?:user|group|ibay|machine)$} or $key eq 'admin'); |
603 |
- |
604 |
- $dn = "cn=$key,ou=Groups,$ldapBase"; |
605 |
- utf8::upgrade($dn); |
606 |
- |
607 |
- $dnmap->{$key}->{group} = $dn; |
608 |
- |
609 |
- $ldif->{$dn}->{objectClass} = [ qw(posixGroup) ]; |
610 |
- $ldif->{$dn}->{cn} = $key; |
611 |
- $ldif->{$dn}->{gidNumber} = $gid; |
612 |
- $ldif->{$dn}->{memberUid} = [ split /\s+/, $members ]; |
613 |
- |
614 |
- if ($type eq 'group') |
615 |
- { |
616 |
- push @{$ldif->{$dn}->{objectClass}}, 'mailboxRelatedObject'; |
617 |
- $ldif->{$dn}->{mail} = "$key\@$DomainName"; |
618 |
- $ldif->{$dn}->{description} = $ldif->{$dnmap->{$key}->{user}}->{cn} if exists $ldif->{$dnmap->{$key}->{user}}->{cn}; |
619 |
- } |
620 |
- } |
621 |
- endgrent(); |
622 |
- |
623 |
- # Nobody and shared are special groups used by samba |
624 |
- foreach my $group (qw/nobody shared www/) |
625 |
- { |
626 |
- $dn = "cn=$group,ou=Groups,$ldapBase"; |
627 |
- utf8::upgrade($dn); |
628 |
- |
629 |
- $dnmap->{$group}->{group} = $dn; |
630 |
- |
631 |
- $ldif->{$dn}->{objectClass} = [ qw(posixGroup) ]; |
632 |
- @{$ldif->{$dn}}{'cn','junk','gidNumber','memberUid'} = getgrnam($group); |
633 |
- $ldif->{$dn}->{memberUid} = [ split /\s+/, $ldif->{$dn}->{memberUid} ]; |
634 |
- |
635 |
- if ($group eq 'shared'){ |
636 |
- push @{$ldif->{$dn}->{objectClass}}, 'mailboxRelatedObject'; |
637 |
- $ldif->{$dn}->{mail} = "everyone\@$DomainName"; |
638 |
- } |
639 |
- } |
640 |
- endgrent(); |
641 |
- |
642 |
- # Read in samba user details |
643 |
- if ( -f "$schema" and -x '/usr/bin/pdbedit' ) |
644 |
- { |
645 |
- foreach my $line (`/usr/bin/pdbedit -Lw 2> /dev/null`) |
646 |
- { |
647 |
- my ($key,undef,$lmpass,$ntpass) = split(/:/,$line); |
648 |
- next unless exists $dnmap->{$key}; |
649 |
- |
650 |
- push @{$ldif->{$dnmap->{$key}->{user}}->{objectClass}}, 'sambaSamAccount'; |
651 |
- $ldif->{$dnmap->{$key}->{user}}->{sambaLMPassword} = $lmpass; |
652 |
- $ldif->{$dnmap->{$key}->{user}}->{sambaNTPassword} = $ntpass; |
653 |
- |
654 |
- foreach my $info (`/usr/bin/pdbedit -v '$key' 2> /dev/null`){ |
655 |
- $ldif->{$dnmap->{$key}->{user}}->{sambaSID} = $1 if $info =~ m{User SID:\s+(S-.*)$}; |
656 |
- $ldif->{$dnmap->{$key}->{user}}->{displayName} = $1 if $info =~ m{Full Name:\s+(.*)$}; |
657 |
- $ldif->{$dnmap->{$key}->{user}}->{sambaPrimaryGroupSID} = $1 if $info =~ m{Primary Group SID:\s+(S-.*)$}; |
658 |
- $ldif->{$dnmap->{$key}->{user}}->{sambaAcctFlags} = $1 if $info =~ m{Account Flags:\s+(.*)$}; |
659 |
- $ldif->{$dnmap->{$key}->{user}}->{sambaPwdLastSet} = str2time($1) if $info =~ m{Password last set:\s+(.*)$}; |
660 |
- } |
661 |
- } |
662 |
- } |
663 |
- |
664 |
- # Read in samba group mappings |
665 |
- if ( -f "$schema" and -x '/usr/bin/net' ) |
666 |
- { |
667 |
- foreach (`/usr/bin/net groupmap list 2> /dev/null`){ |
668 |
- chomp; |
669 |
- next if m{\(S-1-5-32-\d+\)}; |
670 |
- if (/^(.*) \((S-.*-\d+)\) -> (.*)$/) |
671 |
- { |
672 |
- next unless exists $dnmap->{$3}; |
673 |
- |
674 |
- push @{$ldif->{$dnmap->{$3}->{group}}->{objectClass}}, 'sambaGroupMapping'; |
675 |
- $ldif->{$dnmap->{$3}->{group}}->{displayName} = $1; |
676 |
- $ldif->{$dnmap->{$3}->{group}}->{sambaSID} = $2; |
677 |
- $ldif->{$dnmap->{$3}->{group}}->{sambaGroupType} = '2'; |
678 |
- } |
679 |
- } |
680 |
- } |
681 |
- |
682 |
- # Ensure that attributes are utf8 |
683 |
- foreach $dn (keys %$ldif) |
684 |
- { |
685 |
- foreach $attr ( keys %{$ldif->{$dn}} ) |
686 |
- { |
687 |
- if ( ref($ldif->{$dn}->{$attr}) eq 'ARRAY' ) |
688 |
- { |
689 |
- for (my $c = 0; $c < scalar(@{$ldif->{$dn}->{$attr}}); $c++) |
690 |
- { |
691 |
- utf8::upgrade($ldif->{$dn}->{$attr}[$c]); |
692 |
- } |
693 |
- } |
694 |
- else |
695 |
- { |
696 |
- utf8::upgrade($ldif->{$dn}->{$attr}); |
697 |
- } |
698 |
- } |
699 |
- } |
700 |
- |
701 |
- $OUT = ""; |
702 |
-} |
703 |
diff -ruN e-smith-ldap-5.2.0.ldap-init/root/var/service/ldap/convert_ldif e-smith-ldap-5.2.0/root/var/service/ldap/convert_ldif |
704 |
--- e-smith-ldap-5.2.0.ldap-init/root/var/service/ldap/convert_ldif 2010-12-01 11:12:29.000000000 -0700 |
705 |
+++ e-smith-ldap-5.2.0/root/var/service/ldap/convert_ldif 1969-12-31 17:00:00.000000000 -0700 |
706 |
@@ -1,67 +0,0 @@ |
707 |
-#! /usr/bin/perl |
708 |
- |
709 |
-use strict; |
710 |
-use warnings; |
711 |
- |
712 |
- |
713 |
-use Net::LDAP::LDIF; |
714 |
-use esmith::util; |
715 |
- |
716 |
-my $olddomain = shift; |
717 |
-my $newdomain = shift; |
718 |
- |
719 |
-my $ldif = Net::LDAP::LDIF->new( "/dev/stdin", "r", onerror => 'undef' ); |
720 |
-my $writer = Net::LDAP::LDIF->new("/dev/stdout", "w", onerror => 'undef' ); |
721 |
- |
722 |
-my $new = esmith::util::ldapBase($newdomain); |
723 |
-my $old = esmith::util::ldapBase($olddomain); |
724 |
- |
725 |
-while( not $ldif->eof()) |
726 |
-{ |
727 |
- my $entry = $ldif->read_entry(); |
728 |
- if ($ldif->error()) |
729 |
- { |
730 |
- print "Error msg: ", $ldif->error(), "\n"; |
731 |
- print "Error lines:\n", $ldif->error_lines(), "\n"; |
732 |
- next; |
733 |
- } |
734 |
- next unless $entry; |
735 |
- my $dn = $entry->dn; |
736 |
- my @object_classes = $entry->get_value('objectClass'); |
737 |
- my %object_classes = map { $_ => 1 } @object_classes; |
738 |
- if ($dn eq $old) |
739 |
- { |
740 |
- # this is the domain container object - objectClasses will be |
741 |
- # 'top' and 'domain' |
742 |
- my $dc = $new; |
743 |
- $dc =~ s/,.*//g; |
744 |
- $dc =~ s/^dc=//; |
745 |
- $entry->replace(dc => $dc); |
746 |
- } |
747 |
- if ($object_classes{group}) |
748 |
- { |
749 |
- # We used to create group entries with invalid objectClass group |
750 |
- # - fix these if we find them |
751 |
- # possibly not required any more, but harmless |
752 |
- @object_classes = grep { $_ ne 'group' } @object_classes; |
753 |
- $entry->replace(objectClass => [ @object_classes, 'posixGroup' ] ); |
754 |
- } |
755 |
- # do any other object transformations |
756 |
- |
757 |
- # Update the mail attributes |
758 |
- if ($entry->exists('mail')){ |
759 |
- my @newmails = (); |
760 |
- foreach ($entry->get_value('mail')){ |
761 |
- $_ =~ s/\@$olddomain$/\@$newdomain/; |
762 |
- push (@newmails,$_); |
763 |
- } |
764 |
- $entry->replace(mail => [ @newmails ]); |
765 |
- } |
766 |
- |
767 |
- # Update basedb suffix |
768 |
- $dn =~ s/$old$/$new/; |
769 |
- $entry->dn($dn); |
770 |
- $writer->write($entry); |
771 |
-} |
772 |
-$ldif->done( ); |
773 |
- |
774 |
diff -ruN e-smith-ldap-5.2.0.ldap-init/root/var/service/ldap/ldif-fix e-smith-ldap-5.2.0/root/var/service/ldap/ldif-fix |
775 |
--- e-smith-ldap-5.2.0.ldap-init/root/var/service/ldap/ldif-fix 1969-12-31 17:00:00.000000000 -0700 |
776 |
+++ e-smith-ldap-5.2.0/root/var/service/ldap/ldif-fix 2010-12-01 12:09:24.000000000 -0700 |
777 |
@@ -0,0 +1,414 @@ |
778 |
+#!/usr/bin/perl -T |
779 |
+ |
780 |
+use strict; |
781 |
+use warnings; |
782 |
+use Net::LDAP; |
783 |
+use Net::LDAP::LDIF; |
784 |
+use Date::Parse; |
785 |
+use esmith::ConfigDB; |
786 |
+use esmith::AccountsDB; |
787 |
+use esmith::util; |
788 |
+use Getopt::Long qw(:config bundling); |
789 |
+ |
790 |
+$ENV{'PATH'} = '/bin:/usr/bin:/sbin:/usr/sbin'; |
791 |
+$ENV{'LANG'} = 'C'; |
792 |
+ |
793 |
+sub dnsort { |
794 |
+ my %type = ( add => 1, modrdn => 2, moddn => 2, modify => 3, delete => 4); |
795 |
+ my %attr = ( dc => 1, ou => 2, cn => 3, uid => 4); |
796 |
+ |
797 |
+ my ($oa) = ($a->get_value('newrdn') || $a->dn) =~ /^([^=]+)=/; |
798 |
+ my ($ob) = ($b->get_value('newrdn') || $b->dn) =~ /^([^=]+)=/; |
799 |
+ my ($ua, $ub) = map { my $tu = $_->get_value('uidnumber'); defined $tu && $tu ne '' ? $tu : -1 } ($a, $b); |
800 |
+ my ($ga, $gb) = map { my $tg = $_->get_value('gidnumber'); defined $tg && $tg ne '' ? $tg : -1 } ($a, $b); |
801 |
+ |
802 |
+ ($attr{$oa} || 9) <=> ($attr{$ob} || 9) || ($type{$a->changetype} || 9) <=> ($type{$b->changetype} || 9) || |
803 |
+ $ua <=> $ub || $ga <=> $gb || ($a->get_value('newrdn') || $a->dn) cmp ($b->get_value('newrdn') || $b->dn); |
804 |
+} |
805 |
+ |
806 |
+my $c = esmith::ConfigDB->open_ro; |
807 |
+my $a = esmith::AccountsDB->open_ro; |
808 |
+ |
809 |
+my $auth = $c->get('ldap')->prop('Authentication') || 'disabled'; |
810 |
+my $schema = '/etc/openldap/schema/samba.schema'; |
811 |
+ |
812 |
+my $domain = $c->get('DomainName')->value; |
813 |
+my $basedn = esmith::util::ldapBase($domain); |
814 |
+ |
815 |
+my $userou = 'ou=Users'; |
816 |
+my $groupou = 'ou=Groups'; |
817 |
+my $compou = 'ou=Computers'; |
818 |
+ |
819 |
+my ($dc) = split /\./, $domain; |
820 |
+my $company = $c->get_prop('ldap', 'defaultCompany') || $domain; |
821 |
+ |
822 |
+my %opt; |
823 |
+GetOptions ( \%opt, "diff|d", "update|u", "input|i=s", "output|o=s" ); |
824 |
+$opt{input} = '/usr/sbin/slapcat -c 2> /dev/null|' unless $opt{input} && ($opt{input} eq '-' || -f "$opt{input}" || -c "$opt{input}"); |
825 |
+$opt{diff} = 1 if $opt{update}; |
826 |
+if ( $opt{output} && $opt{output} =~ m{^([-\w/.]+)$}) { |
827 |
+ $opt{output} = $1; |
828 |
+} else { |
829 |
+ $opt{output} = '-'; |
830 |
+} |
831 |
+ |
832 |
+my ($data, $dn); |
833 |
+ |
834 |
+# Top object (base) |
835 |
+$data->{$basedn} = { |
836 |
+ objectclass => [qw/organization dcObject top/], |
837 |
+ dc => $dc, |
838 |
+ o => $company, |
839 |
+}; |
840 |
+ |
841 |
+# Top containers for users/groups/computers |
842 |
+foreach (qw/Users Groups Computers/) { |
843 |
+ $data->{"ou=$_,$basedn"} = { |
844 |
+ objectclass => [qw/organizationalUnit top/], |
845 |
+ ou => $_, |
846 |
+ }; |
847 |
+} |
848 |
+ |
849 |
+# Common accounts needed for SME to work properly |
850 |
+$data->{"cn=nobody,$groupou,$basedn"}->{objectclass} = [ qw/posixGroup/ ]; |
851 |
+$data->{"uid=www,$userou,$basedn"}->{objectclass} = [ qw/account/ ]; |
852 |
+$data->{"cn=www,$groupou,$basedn"} = { objectclass => [ qw/posixGroup/ ], memberuid => [ qw/admin/ ] }; |
853 |
+$data->{"cn=shared,$groupou,$basedn"} = { |
854 |
+ objectclass => [ qw/posixGroup mailboxRelatedObject/ ], |
855 |
+ mail => "everyone\@$domain", |
856 |
+ memberuid => [ qw/www/ ] |
857 |
+}; |
858 |
+ |
859 |
+# Read in accounts database information |
860 |
+foreach my $acct ($a->get('admin'), $a->users, $a->groups, $a->ibays, $a->get_all_by_prop(type => 'machine')) { |
861 |
+ my $key = $acct->key; |
862 |
+ my $type = $acct->prop('type'); |
863 |
+ |
864 |
+ next if $key eq 'Primary'; |
865 |
+ |
866 |
+ $dn = "uid=$key,".($type eq 'machine' ? $compou : $userou).",$basedn"; |
867 |
+ if ($type =~ /^(?:user|group|machine|ibay)$/ || $key eq 'admin') { |
868 |
+ if ($type eq 'user' || $key eq 'admin') { |
869 |
+ # Allow removal of obsolete person objectclass and samba attributes |
870 |
+ push @{$data->{$dn}->{_delete}->{objectclass}}, 'person'; |
871 |
+ |
872 |
+ |
873 |
+ push @{$data->{$dn}->{objectclass}}, 'inetOrgPerson'; |
874 |
+ $data->{$dn}->{mail} = "$key\@$domain"; |
875 |
+ @{$data->{$dn}}{qw/givenname sn telephonenumber o ou l street/} = |
876 |
+ map { $acct->prop($_) || [] } qw/FirstName LastName Phone Company Dept City Street/; |
877 |
+ $data->{$dn}->{cn} = $data->{$dn}->{gecos} = $acct->prop('FirstName').' '.$acct->prop('LastName'); |
878 |
+ } |
879 |
+ else { |
880 |
+ push @{$data->{$dn}->{objectclass}}, 'account'; |
881 |
+ } |
882 |
+ |
883 |
+ # users/ibays need to be a member of shared |
884 |
+ push @{$data->{"cn=shared,$groupou,$basedn"}->{memberuid}}, $key if $type =~ /^(user|ibay)$/ || $key eq 'admin'; |
885 |
+ |
886 |
+ if ($auth ne 'enabled') { |
887 |
+ # Allow removal of shadow properties |
888 |
+ push @{$data->{$dn}->{_delete}->{objectclass}}, 'shadowAccount'; |
889 |
+ $data->{$dn}->{_delete}->{lc($_)} = 1 foreach qw/userPassword shadowLastChange shadowMin shadowMax |
890 |
+ shadowWarning shadowInactive shadowExpire shadowFlag/; |
891 |
+ |
892 |
+ if ( -f "$schema" ) { |
893 |
+ # If we will be adding samba properties then allow removal |
894 |
+ push @{$data->{$dn}->{_delete}->{objectclass}}, 'sambaSamAccount'; |
895 |
+ $data->{$dn}->{_delete}->{lc($_)} = 1 foreach qw/displayName sambaAcctFlags sambaLMPassword sambaNTPassword |
896 |
+ sambaNTPassword sambaPrimaryGroupSID sambaPwdLastSet sambaSID/; |
897 |
+ } |
898 |
+ } |
899 |
+ } |
900 |
+ |
901 |
+ $dn = "cn=$key,$groupou,$basedn"; |
902 |
+ push @{$data->{$dn}->{objectclass}}, 'posixGroup'; |
903 |
+ if ($type eq 'group') { |
904 |
+ # Allways replace memberuid with new set |
905 |
+ $data->{$dn}->{_delete}->{memberuid} = 1; |
906 |
+ |
907 |
+ push @{$data->{$dn}->{objectclass}}, 'mailboxRelatedObject'; |
908 |
+ |
909 |
+ $data->{$dn}->{mail} = "$key\@$domain"; |
910 |
+ $data->{$dn}->{description} = $acct->prop('Description') || []; |
911 |
+ push @{$data->{$dn}->{memberuid}}, split /,/, ($acct->prop('Members') || ''); |
912 |
+ |
913 |
+ # www needs to be a memeber of every group |
914 |
+ push @{$data->{$dn}->{memberuid}}, 'www'; |
915 |
+ |
916 |
+ if ($auth ne 'enabled' && -f "$schema" ) { |
917 |
+ # If we will be adding samba properties then allow removal |
918 |
+ push @{$data->{$dn}->{_delete}->{objectclass}}, 'sambaGroupMapping'; |
919 |
+ $data->{$dn}->{_delete}->{lc($_)} = 1 foreach qw/displayName sambaGroupType sambaSID/; |
920 |
+ } |
921 |
+ } |
922 |
+ elsif ($type eq 'ibay') { |
923 |
+ $dn = "cn=".$acct->prop('Group').",$groupou,$basedn"; |
924 |
+ push @{$data->{$dn}->{memberuid}}, $acct->key; |
925 |
+ } |
926 |
+} |
927 |
+ |
928 |
+if ($auth ne 'enabled') { |
929 |
+ # Read in information from unix (passwd) system |
930 |
+ open PASSWD, '/etc/passwd'; |
931 |
+ while (<PASSWD>) { |
932 |
+ chomp; |
933 |
+ my @passwd = split /:/, $_; |
934 |
+ next unless scalar @passwd == 7; |
935 |
+ |
936 |
+ $dn = "uid=$passwd[0],".($passwd[0] =~ /\$$/ ? $compou : $userou).",$basedn"; |
937 |
+ next unless exists $data->{$dn}; |
938 |
+ |
939 |
+ push @{$data->{$dn}->{objectclass}}, 'posixAccount'; |
940 |
+ @{$data->{$dn}}{qw/cn uid uidnumber gidnumber homedirectory loginshell gecos/} = |
941 |
+ map { $passwd[$_] ? $passwd[$_] : [] } (4,0,2,3,5,6,4); |
942 |
+ } |
943 |
+ close (PASSWD); |
944 |
+ |
945 |
+ # Shadow file defaults (pulled from cpu.conf) |
946 |
+ my %shadow_def = ( 1 => [], 2 => 11192, 3 => -1, 4 => 99999, 5 => 7, 6 => -1, 7 => -1, 8 => 134538308 ); |
947 |
+ |
948 |
+ # Read in information from unix (shadow) system |
949 |
+ open SHADOW, '/etc/shadow'; |
950 |
+ while (<SHADOW>) { |
951 |
+ chomp; |
952 |
+ my @shadow = split /:/, $_; |
953 |
+ next unless scalar @shadow >= 6; |
954 |
+ $shadow[1] = '!*' if $shadow[1] eq '!!'; |
955 |
+ $shadow[1] = "{CRYPT}$shadow[1]" unless $shadow[1] =~ /^\{/; |
956 |
+ |
957 |
+ $dn = "uid=$shadow[0],".($shadow[0] =~ /\$$/ ? $compou : $userou).",$basedn"; |
958 |
+ next unless exists $data->{$dn}; |
959 |
+ |
960 |
+ push @{$data->{$dn}->{objectclass}}, 'shadowAccount'; |
961 |
+ @{$data->{$dn}}{ map { lc($_) } qw/userPassword shadowLastChange shadowMin shadowMax shadowWarning shadowInactive |
962 |
+ shadowExpire shadowFlag/} = map { $shadow[$_] ? $shadow[$_] : $shadow_def{$_} } (1..8); |
963 |
+ } |
964 |
+ close (SHADOW); |
965 |
+ |
966 |
+ # Read in information from unix (group) system |
967 |
+ open GROUP, '/etc/group'; |
968 |
+ while (<GROUP>) { |
969 |
+ chomp; |
970 |
+ my @group = split /:/, $_; |
971 |
+ next unless scalar @group >= 3; |
972 |
+ $group[3] = [ split /,/, ($group[3] || '') ]; |
973 |
+ |
974 |
+ $dn = "cn=$group[0],$groupou,$basedn"; |
975 |
+ next unless exists $data->{$dn}; |
976 |
+ |
977 |
+ push @{$data->{$dn}->{objectclass}}, 'posixGroup'; |
978 |
+ @{$data->{$dn}}{qw/cn gidnumber/} = map { $group[$_] ? $group[$_] : [] } (0,2); |
979 |
+ push @{$data->{$dn}->{memberuid}}, @{$group[3]}; |
980 |
+ } |
981 |
+ close (GROUP); |
982 |
+ |
983 |
+ my %smbprop = ( |
984 |
+ 'User SID' => 'sambasid', |
985 |
+ 'Account Flags' => 'sambaacctflags', |
986 |
+ 'Primary Group SID' => 'sambaprimarygroupsid', |
987 |
+ 'Full Name' => 'displayname', |
988 |
+ 'Password last set' => 'sambapwdlastset', |
989 |
+ ); |
990 |
+ |
991 |
+ # Read in information from unix (smbpasswd) system |
992 |
+ if ( -f "$schema" && -x '/usr/bin/pdbedit' ) { |
993 |
+ $dn = undef; |
994 |
+ open SMBDETAIL, '/usr/bin/pdbedit -vL 2> /dev/null|'; |
995 |
+ while (<SMBDETAIL>) { |
996 |
+ chomp; |
997 |
+ |
998 |
+ $dn = ("uid=$1,".($1 =~ /\$$/ ? $compou : $userou).",$basedn") if m/^Unix username:\s+(\S.*)$/; |
999 |
+ next unless $dn && exists $data->{$dn}; |
1000 |
+ |
1001 |
+ # Map the samba account properties that we care about |
1002 |
+ $data->{$dn}->{$smbprop{$1}} = ($2 ? str2time($2) : (defined $3 ? $3 : [])) |
1003 |
+ if m/^(.+):\s+(?:(\S.*\d{4} \d{2}:\d{2}:\d{2}.*)|(.*))$/ && exists $smbprop{$1}; |
1004 |
+ } |
1005 |
+ close (SMBDETAIL); |
1006 |
+ |
1007 |
+ open SMBPASSWD, '/usr/bin/pdbedit -wL 2> /dev/null|'; |
1008 |
+ while (<SMBPASSWD>) { |
1009 |
+ chomp; |
1010 |
+ my @smbpasswd = split /:/, $_; |
1011 |
+ next unless scalar @smbpasswd >= 6; |
1012 |
+ |
1013 |
+ $dn = "uid=$smbpasswd[0],".($smbpasswd[0] =~ /\$$/ ? $compou : $userou).",$basedn"; |
1014 |
+ next unless exists $data->{$dn} && exists $data->{$dn}->{uidnumber} && $data->{$dn}->{uidnumber} eq $smbpasswd[1]; |
1015 |
+ |
1016 |
+ push @{$data->{$dn}->{objectclass}}, 'sambaSamAccount'; |
1017 |
+ @{$data->{$dn}}{qw/sambalmpassword sambantpassword/} = map { $smbpasswd[$_] ? $smbpasswd[$_] : [] } (2,3); |
1018 |
+ } |
1019 |
+ close (SMBPASSWD); |
1020 |
+ } |
1021 |
+ |
1022 |
+ if ( -f "$schema" && -x '/usr/bin/net' ) { |
1023 |
+ open GROUPMAP, '/usr/bin/net groupmap list 2> /dev/null|'; |
1024 |
+ while (<GROUPMAP>) { |
1025 |
+ chomp; |
1026 |
+ |
1027 |
+ if (m/^(.+) \((.+)\) -> (.+)$/) { |
1028 |
+ # Skip local machine accounts |
1029 |
+ next if $2 =~ /S-1-5-32-\d+/; |
1030 |
+ |
1031 |
+ $dn = "cn=$3,$groupou,$basedn"; |
1032 |
+ next unless exists $data->{$dn}; |
1033 |
+ |
1034 |
+ push @{$data->{$dn}->{objectclass}}, 'sambaGroupMapping'; |
1035 |
+ @{$data->{$dn}}{qw/displayname sambasid sambagrouptype/} = ($1, $2, 2); |
1036 |
+ } |
1037 |
+ } |
1038 |
+ close (GROUPMAP); |
1039 |
+ } |
1040 |
+} |
1041 |
+ |
1042 |
+my @ldif; |
1043 |
+ |
1044 |
+# Loop through ldap data and update as necessary |
1045 |
+my $reader = Net::LDAP::LDIF->new( $opt{input}, 'r', onerror => 'undef' ); |
1046 |
+while( not $reader->eof()) { |
1047 |
+ my $entry = $reader->read_entry() || next; |
1048 |
+ $dn = $entry->dn; |
1049 |
+ |
1050 |
+ # Ensure the basedn is correct |
1051 |
+ $dn = "$1$basedn" if $dn =~ /^((?:(?!dc=)[^,]+,)*)dc=/; |
1052 |
+ |
1053 |
+ # Ensure correct ou is part of user/groups/computers |
1054 |
+ if ($dn =~ /^(uid=([^,\$]+)(\$)?),((?:(?!dc=)[^,]+,)*)dc=/) { |
1055 |
+ if ( defined $3 && $3 eq '$') { |
1056 |
+ $dn = "$1,$compou,$basedn"; |
1057 |
+ } |
1058 |
+ elsif (grep /posixGroup/, @{$entry->get_value('objectclass', asref => 1) || []}) { |
1059 |
+ $dn = "cn=$2,$groupou,$basedn"; |
1060 |
+ |
1061 |
+ # Cleanup attributes that the modrdn will perform |
1062 |
+ $entry->add(cn => $2); |
1063 |
+ $entry->delete(uid => [$2]); |
1064 |
+ } |
1065 |
+ else { |
1066 |
+ $dn = "$1,$userou,$basedn"; |
1067 |
+ } |
1068 |
+ } |
1069 |
+ elsif ($dn =~ /^(cn=[^,]+),((?:(?!dc=)[^,]+,)*)dc=/) { |
1070 |
+ $dn = "$1,$groupou,$basedn" unless $2 =~ /^ou=auto\./; |
1071 |
+ } |
1072 |
+ |
1073 |
+ # Don't process records twice |
1074 |
+ next if $data->{$dn}->{_done}; |
1075 |
+ |
1076 |
+ # Rename existing entry into place if we can |
1077 |
+ if ($dn ne $entry->dn) { |
1078 |
+ my $rdn = Net::LDAP::Entry->new; |
1079 |
+ $rdn->dn($entry->dn); |
1080 |
+ $rdn->changetype('modrdn'); |
1081 |
+ my ($newdn, $newbase) = split /,/, $dn, 2; |
1082 |
+ $rdn->add(newrdn => $newdn, deleteoldrdn => 1, newsuperior => $newbase); |
1083 |
+ push @ldif, $rdn; |
1084 |
+ |
1085 |
+ # Now we can change the entry to new dn |
1086 |
+ $entry->dn($dn); |
1087 |
+ } |
1088 |
+ |
1089 |
+ # Change type to modify so that we can keep track of changes we make |
1090 |
+ $entry->changetype('modify'); |
1091 |
+ |
1092 |
+ # Hack to make upgrades work (add calEntry if calFGUrl attributes exists) |
1093 |
+ if ($entry->exists('calFBURL') && -f "/etc/openldap/schema/rfc2739.schema") { |
1094 |
+ push @{$data->{$dn}->{objectclass}}, 'calEntry'; |
1095 |
+ } |
1096 |
+ |
1097 |
+ my %attributes = (); |
1098 |
+ @attributes{ keys %{$data->{$dn}}, exists $data->{$dn}->{_delete} ? map { lc($_) } keys %{$data->{$dn}->{_delete}} : () } = (); |
1099 |
+ |
1100 |
+ foreach my $attr (sort keys %attributes) { |
1101 |
+ # Skip the pseudo attributes |
1102 |
+ next if $attr =~ /^_/; |
1103 |
+ |
1104 |
+ my @l = @{$entry->get_value($attr, asref => 1) || []}; |
1105 |
+ my @u = exists $data->{$dn}->{$attr} ? (ref $data->{$dn}->{$attr} ? @{$data->{$dn}->{$attr}} : ($data->{$dn}->{$attr})) : (); |
1106 |
+ |
1107 |
+ # Figure out differences between attributes |
1108 |
+ my (@lonly, @uonly, @donly, %lseen, %useen, %dseen) = () x 6; |
1109 |
+ |
1110 |
+ # Unique lists of what is in ldap and what needs to be in ldap |
1111 |
+ @lseen{@l} = (); |
1112 |
+ @useen{@u} = (); |
1113 |
+ |
1114 |
+ # Create list of attributes that aren't in the other |
1115 |
+ @uonly = grep { ! exists $lseen{$_} } keys %useen; |
1116 |
+ @lonly = grep { ! exists $useen{$_} } keys %lseen; |
1117 |
+ |
1118 |
+ # Determine which of the ldap only attributes we need to remove |
1119 |
+ if ((keys %useen == 1 && keys %lseen == 1) || (keys %useen == 0 && exists $data->{$dn}->{$attr})) { |
1120 |
+ # Replacing a single entry or erasing entire entry |
1121 |
+ @donly = @lonly; |
1122 |
+ } |
1123 |
+ elsif ($data->{$dn}->{_delete} && $data->{$dn}->{_delete}->{$attr}) { |
1124 |
+ if (my $ref = ref($data->{$dn}->{_delete}->{$attr})) { |
1125 |
+ # Map hash keys or array elemts to valid values to delete |
1126 |
+ @dseen{$ref eq 'HASH' ? keys %{$data->{$dn}->{_delete}->{$attr}} : @{$data->{$dn}->{_delete}->{$attr}}} = (); |
1127 |
+ @donly = grep { exists $dseen{$_} } @lonly; |
1128 |
+ } |
1129 |
+ else { |
1130 |
+ # Permission to remove all values |
1131 |
+ @donly = @lonly; |
1132 |
+ } |
1133 |
+ } |
1134 |
+ |
1135 |
+ if (@donly && @donly == @lonly) { |
1136 |
+ # If we are removing all ldap only attributes do a remove or full delete |
1137 |
+ if (@uonly) { |
1138 |
+ $entry->replace($attr => [ @uonly ]); |
1139 |
+ } |
1140 |
+ else { |
1141 |
+ $entry->delete($attr => [ @donly == keys %lseen ? () : @donly ]); |
1142 |
+ } |
1143 |
+ } |
1144 |
+ else { |
1145 |
+ $entry->delete($attr => [ @donly ]) if @donly; |
1146 |
+ $entry->add($attr => [ @uonly ]) if @uonly; |
1147 |
+ } |
1148 |
+ } |
1149 |
+ |
1150 |
+ $data->{$dn}->{_done} = 1; |
1151 |
+ push @ldif, $entry; |
1152 |
+} |
1153 |
+$reader->done(); |
1154 |
+ |
1155 |
+# Add missing records that didn't exist in ldap yet |
1156 |
+foreach $dn (grep { ! exists $data->{$_}->{_done} } sort keys %$data) { |
1157 |
+ my $entry = Net::LDAP::Entry->new; |
1158 |
+ $entry->dn($dn); |
1159 |
+ |
1160 |
+ foreach my $attr (sort keys %{$data->{$dn}}) { |
1161 |
+ # Skip the pseudo attributes |
1162 |
+ next if $attr =~ /^_/; |
1163 |
+ |
1164 |
+ my %seen = (); |
1165 |
+ @seen{ref $data->{$dn}->{$attr} ? @{$data->{$dn}->{$attr}} : ($data->{$dn}->{$attr})} = (); |
1166 |
+ $entry->add($attr => [ sort keys %seen ]) if keys %seen != 0; |
1167 |
+ } |
1168 |
+ |
1169 |
+ push @ldif, $entry; |
1170 |
+} |
1171 |
+ |
1172 |
+#------------------------------------------------------------ |
1173 |
+# Update LDAP database entry. |
1174 |
+#------------------------------------------------------------ |
1175 |
+my $ldap; |
1176 |
+if ($opt{update}) { |
1177 |
+ $ldap = Net::LDAP->new('localhost') or die "$@"; |
1178 |
+ $ldap->bind( dn => "cn=root,$basedn", password => esmith::util::LdapPassword() ); |
1179 |
+} |
1180 |
+ |
1181 |
+my $writer = Net::LDAP::LDIF->new( $opt{output}, 'w', onerror => 'undef', wrap => 0, sort => 1, change => $opt{diff} ); |
1182 |
+foreach my $entry (sort dnsort @ldif) { |
1183 |
+ if ($opt{update} && ($entry->changetype ne 'modify' || @{$entry->{changes}}) ) { |
1184 |
+ my $result = $entry->update($ldap); |
1185 |
+ warn "Failure to ",$entry->changetype," ",$entry->dn,": ",$result->error,"\n" if $result->code; |
1186 |
+ } |
1187 |
+ |
1188 |
+ if ($writer->{change} || $entry->changetype !~ /modr?dn/) { |
1189 |
+ $writer->write_entry($entry); |
1190 |
+ } |
1191 |
+} |
1192 |
diff -ruN e-smith-ldap-5.2.0.ldap-init/root/var/service/ldap/run e-smith-ldap-5.2.0/root/var/service/ldap/run |
1193 |
--- e-smith-ldap-5.2.0.ldap-init/root/var/service/ldap/run 2010-12-01 11:12:29.000000000 -0700 |
1194 |
+++ e-smith-ldap-5.2.0/root/var/service/ldap/run 2010-12-01 12:08:53.000000000 -0700 |
1195 |
@@ -2,27 +2,22 @@ |
1196 |
|
1197 |
exec 2>&1 |
1198 |
|
1199 |
-domain=$(/sbin/e-smith/config get DomainName) |
1200 |
-old_domain=$(readlink ldif) |
1201 |
- |
1202 |
-loglevel=$(/sbin/e-smith/config getprop ldap LogLevel || echo 256) |
1203 |
- |
1204 |
./control/1 |
1205 |
|
1206 |
-if [ -n "$old_domain" ] |
1207 |
-then |
1208 |
- old_domain=$(basename $old_domain | sed s/.ldif//) |
1209 |
- old_ldif="/home/e-smith/db/ldap/$old_domain.ldif" |
1210 |
-fi |
1211 |
- |
1212 |
+domain=$(/sbin/e-smith/config get DomainName) |
1213 |
ldif="/home/e-smith/db/ldap/$domain.ldif" |
1214 |
|
1215 |
-if [ "$old_domain" != "$domain" ] |
1216 |
+if [ -e ldif ] |
1217 |
then |
1218 |
- # The domain name has changed, so we need to delete |
1219 |
- # the old directory contents. We still have the old |
1220 |
- # dump. |
1221 |
- find /var/lib/ldap -type f | xargs rm -f |
1222 |
+ old_ldif=$(readlink ldif) |
1223 |
+ if [ "$old_ldif" != "$ldif" ] |
1224 |
+ then |
1225 |
+ # The domain name has changed, so we need to delete |
1226 |
+ # the old directory contents. We still have the old |
1227 |
+ # dump. |
1228 |
+ mv -f $old_ldif $ldif |
1229 |
+ find /var/lib/ldap -type f | xargs rm -f |
1230 |
+ fi |
1231 |
fi |
1232 |
|
1233 |
if [ -f /var/lib/ldap/nextid.dbb ] |
1234 |
@@ -44,19 +39,15 @@ |
1235 |
# Prime directory if required |
1236 |
if [ \! -f /var/lib/ldap/id2entry.bdb ] |
1237 |
then |
1238 |
- if [ -e "$old_ldif" ] |
1239 |
+ if [ -e ldif ] |
1240 |
then |
1241 |
- grep -q "objectClass: dcObject" "$ldif" || /sbin/e-smith/expand-template /home/e-smith/db/ldap/ldif |
1242 |
- perl ./convert_ldif $old_domain $domain < $old_ldif | \ |
1243 |
- setuidgid ldap slapadd -c |
1244 |
+ ./ldif-fix -i ldif | setuidgid ldap slapadd -c |
1245 |
else |
1246 |
- if [ \! -e "$ldif" ] |
1247 |
- then |
1248 |
- /sbin/e-smith/expand-template /home/e-smith/db/ldap/ldif |
1249 |
- fi |
1250 |
- setuidgid ldap slapadd -c < $ldif |
1251 |
+ ./ldif-fix -i /dev/null | setuidgid ldap slapadd -c |
1252 |
fi |
1253 |
fi |
1254 |
|
1255 |
+loglevel=$(/sbin/e-smith/config getprop ldap LogLevel || echo 256) |
1256 |
+ |
1257 |
# Now run daemon |
1258 |
exec /usr/sbin/slapd -4 -u ldap -d $loglevel -s 0 -h "ldap:/// ldaps:/// ldapi:///" |