Re: Draft script to migrate LDAP entries from Etch to Lenny
[Oded Naveh]
> Hi, perhaps the wiki page on Etch upgrade to Lenny would help,
> though kind of the other way around.
> http://wiki.debian.org/DebianEdu/Documentation/Lenny/Upgrades
Yes, it helps. :)
Here is a second draft. Still untested, but now able to add the
missing LDAP attributes and handle more objectclasses.
#!/usr/bin/perl
#
# Script to migrate LDAP objects from a Debian Edu Etch database to an
# Lenny database.
#
# The user and group objects in Etch and Lenny are identical, so no
# editing is required to migrate these.
#
# http://quark.humbug.org.au/publications/ldap/ldap_tut.html
# http://wiki.debian.org/DebianEdu/Status/Lenny/SambaLDAP
use strict;
use warnings;
use Net::LDAP;
use Data::Dumper;
my $etchserver = "localhost";
my $lennyserver = "";
my $base = "dc=skole,dc=skolelinux,dc=no";
my $manager = "cn=admin,ou=People,$base";
my $password = 'secret';
my $uid = "test";
my $ldapetch = Net::LDAP->new($etchserver)
or die "Can't bind to ldap server $etchserver: $!\n";
$ldapetch->bind;
my $ldaplenny;
if ($lennyserver) {
$ldaplenny = Net::LDAP->new($lennyserver)
or die "Can't bind to ldap: $!\n";
$ldaplenny->start_tls();
$ldaplenny->bind(
dn => $manager,
password => $password,
);
}
migrate_users($ldapetch, $ldaplenny);
migrate_groups($ldapetch, $ldaplenny);
migrate_netgroups($ldapetch, $ldaplenny);
migrate_automounts($ldapetch, $ldaplenny);
$ldaplenny->unbind if $ldaplenny;
$ldapetch->unbind;
sub copy_ldap_objects {
my ($ldapetch, $ldaplenny, $ldapfilter, $filterfunc) = @_;
my($mesg) = $ldapetch->search( base => $base, filter => $ldapfilter);
$mesg->code && die $mesg->error;
foreach my $entry ($mesg->all_entries) {
$entry->dump;
# print Dumper($entry);
my $dn = $entry->dn;
my $filter = "(&($ldapfilter)(dn=$dn))";
# print "F: $filter $dn\n";
if ($filterfunc) {
$filterfunc->($entry);
}
if ($ldaplenny) {
my $mesg = $ldaplenny->search( base => $base, filter => $filter);
my $exist = 0 < $mesg->count;
if (!$exist) {
print "Want to add LDAP object:\n";
$entry->dump;
my $result = $entry->update($ldaplenny);
$result->code && warn "failed to add entry: ", $result->error;
} else {
print "Object for $dn exist, not adding\n";
}
} else {
$entry->dump;
}
}
}
# Transform user objects for etch->lenny upgrade
sub migrate_user {
my $objref = shift;
# Make sure user objects with objectClass=sambaSamAccount have a
# sambaPwdLastSet value with content > 0.
my %add =
(
'sambaBadPasswordCount' => 0,
'sambaBadPasswordTime' => 0,
'sambaKickoffTime' => 0,
'sambaLogoffTime' => 0,
'sambaLogonHours' => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',
'sambaLogonTime' => 0,
'sambaPasswordHistory' => '0000000000000000000000000000000000000000000000000000000000000000',
'sambaPwdCanChange' => 0,
'sambaPwdLastSet' => 1,
'sambaPwdMustChange' => 0,
);
if (my @classes = $objref->get_value('objectClass')) {
foreach my $objectclass (@classes) {
if (lc('sambaSamAccount') eq lc($objectclass)) {
for my $key (keys %add) {
my $lastset = $objref->get_value($key);
if ( ! $lastset ) {
$objref->add($key, $add{$key});
} elsif (0 == $lastset ) {
$objref->replace($key, $add{$key});
}
}
}
}
}
}
sub migrate_users {
my ($ldapetch, $ldaplenny) = @_;
copy_ldap_objects($ldapetch, $ldaplenny, '(objectclass=posixAccount)',
\&migrate_user);
}
sub migrate_groups {
my ($ldapetch, $ldaplenny) = @_;
copy_ldap_objects($ldapetch, $ldaplenny, '(objectclass=posixGroup)');
}
sub migrate_netgroups {
my ($ldapetch, $ldaplenny) = @_;
copy_ldap_objects($ldapetch, $ldaplenny, '(objectclass=nisNetgroup)');
}
sub migrate_automounts {
my ($ldapetch, $ldaplenny) = @_;
copy_ldap_objects($ldapetch, $ldaplenny, '(objectclass=automount)');
}
I very much welcome feedback on the approach.
Happy hacking,
--
Petter Reinholdtsen
Reply to: