/[smeserver]/rpms/e-smith-ldap/sme8/e-smith-ldap-5.2.0-ldap-init.patch
ViewVC logotype

Annotation of /rpms/e-smith-ldap/sme8/e-smith-ldap-5.2.0-ldap-init.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (hide annotations) (download)
Wed Dec 1 19:24:58 2010 UTC (14 years ago) by slords
Branch: MAIN
CVS Tags: e-smith-ldap-5_2_0-79_el5_sme, e-smith-ldap-5_2_0-81_el5_sme, e-smith-ldap-5_2_0-72_el5_sme, e-smith-ldap-5_2_0-80_el5_sme, e-smith-ldap-5_2_0-76_el5_sme, e-smith-ldap-5_2_0-74_el5_sme, e-smith-ldap-5_2_0-77_el5_sme, e-smith-ldap-5_2_0-75_el5_sme, e-smith-ldap-5_2_0-78_el5_sme, e-smith-ldap-5_2_0-73_el5_sme, HEAD
* Wed Dec 1 2010 Shad L. Lords <slord@mail.com> 5.2.0-72.sme
- Replace convert_ldif with ldif-fix script [SME: 6244]
- Remove ldif template and expansion [SME: 6421]
- Simplify ldap-update call by calling ldif-fix [SME: 6422]

1 slords 1.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:///"

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed