Zarafa DB to LDAP user plugin conversion
From Zarafa wiki
(Difference between revisions)
Ddebyttere (Talk | contribs) |
|||
| Line 12: | Line 12: | ||
<pre> | <pre> | ||
#!/usr/bin/perl -w | #!/usr/bin/perl -w | ||
| - | |||
use strict; | use strict; | ||
| - | |||
use DBI; | use DBI; | ||
| + | use Net::LDAP; | ||
| - | + | sub readconfig($) { | |
| - | + | my ($fn) = @_; | |
| - | + | my %options; | |
| + | |||
| + | open(CFG, $fn) or die("unable to open ".$fn." config file"); | ||
| + | while (<CFG>) { | ||
| + | if ($_ =~ /^\s*[#!]/) { | ||
| + | next; | ||
| + | } | ||
| + | if ($_ =~ /^\s*(\S+)\s*=\s*([^\r]+)\r?$/) { | ||
| + | my $idx = $1; | ||
| + | my $val = $2; | ||
| + | chomp($val); | ||
| + | $val =~ s/\s+$//; | ||
| + | $options{$idx} = $val; | ||
| + | } | ||
| + | } | ||
| + | close(CFG); | ||
| + | return %options; | ||
} | } | ||
| - | my ($ | + | # @todo, differentiate between users/groups/etc. |
| + | sub get_extern_id($$$) { | ||
| + | my ($lo, $ldap, $db_username) = @_; | ||
| + | my $mesg = $ldap->search(filter => "($lo->{ldap_loginname_attribute}=$db_username)", | ||
| + | base => "$lo->{ldap_search_base}", | ||
| + | attrs => ["$lo->{ldap_loginname_attribute}", "$lo->{ldap_user_unique_attribute}"], | ||
| + | scope => "sub"); | ||
| - | my $ | + | my @entries = $mesg->entries; |
| - | + | # if $mesg->count != 1 fallback on emailaddress lookup? | |
| - | + | if ( $mesg->count == 0 ) { | |
| - | + | print "Error updating $db_username. No entry found in ldap for ($lo->{ldap_loginname_attribute} = $db_username)\n"; | |
| - | + | return ($mesg->count, ""); | |
| - | + | } | |
| - | + | if ( $mesg->count > 1 ) { | |
| - | + | print "Error updating $db_username. Multiple entries found in ldap for ($lo->{ldap_loginname_attribute} = $db_username)\n"; | |
| - | + | return ($mesg->count, ""); | |
| - | + | } | |
| - | + | ||
| - | + | return ($mesg->count, $entries[0]->get_value($lo->{ldap_user_unique_attribute})); | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
} | } | ||
| - | |||
| - | |||
| - | |||
| - | |||
| - | + | my $servercfg = $ARGV[0]; | |
| + | $servercfg = "/etc/zarafa/server.cfg" if (!defined($servercfg)); | ||
| - | + | my %serveropt = readconfig($servercfg); | |
| - | + | if (!defined($serveropt{user_plugin})) { | |
| - | + | print "First argument must be the server configuration file\n"; | |
| - | + | exit(0); | |
| + | } | ||
| + | if ($serveropt{user_plugin} ne "ldap") { | ||
| + | print "You only can change the unique attribute for the ldap user plugin, found: '".$serveropt{user_plugin}."'\n"; | ||
| + | exit(0); | ||
| + | } | ||
| + | my %ldapopt = readconfig($serveropt{user_plugin_config}); | ||
| - | my | + | my $ldapuri = $ldapopt{ldap_protocol}."://".$ldapopt{ldap_host}.":".$ldapopt{ldap_port}; |
| + | my $ldap = Net::LDAP->new($ldapuri) or die ("LDAP connection failed"); | ||
| + | my $msg = $ldap->bind($ldapopt{ldap_bind_user}, password => $ldapopt{ldap_bind_passwd}); | ||
| + | $msg->code && die $msg->error; | ||
| - | my $dbh | + | my ($dbh, $query, $sth, $upd, $udh); |
| - | + | my @row; | |
| - | + | ||
| - | + | $dbh = DBI->connect("dbi:mysql:database=".$serveropt{mysql_database}.";host=".$serveropt{mysql_host}, $serveropt{mysql_user}, $serveropt{mysql_password}) | |
| + | or die $DBI::errstr; | ||
| - | + | $query = "SELECT u.id AS user_id, op.value AS user_name, o.id FROM users AS u JOIN object AS o ON u.externid=o.externid JOIN objectproperty AS op ON o.id=op.objectid AND op.propname='loginname'"; | |
| - | + | $sth = $dbh->prepare($query) or die $DBI::errstr; | |
| + | $sth->execute(); | ||
| - | + | $dbh->begin_work(); | |
| - | + | $dbh->{AutoCommit} = 0; | |
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | + | ||
| - | my $ | + | while (@row = $sth->fetchrow_array) { |
| + | my $db_user_id = $row[0]; | ||
| + | my $db_user_name = $row[1]; | ||
| + | my $db_object_id = $row[2]; | ||
| + | print "Found user '$db_user_name' in database with user_id '$db_user_id'\n"; | ||
| - | + | my ($retval, $extern_id) = get_extern_id(\%ldapopt, $ldap, $db_user_name); | |
| - | + | #print "$retval - $extern_id\n"; | |
| - | + | #print "$db_user_id - $db_user_name\n"; | |
| - | + | if ($retval == 1) { | |
| - | + | $query = "UPDATE users SET externid=? WHERE id=?"; | |
| - | + | $upd = $dbh->prepare($query) | |
| - | + | or die $DBI::errstr; | |
| - | + | $upd->execute($extern_id, $db_user_id); | |
| - | + | $query = "UPDATE object SET externid=? WHERE id=?"; | |
| - | + | $upd = $dbh->prepare($query) | |
| + | or die $DBI::errstr; | ||
| + | $upd->execute($extern_id, $db_object_id); | ||
| + | } | ||
} | } | ||
| - | + | print "Committing changes to database\n"; | |
| - | + | $dbh->commit(); | |
| - | + | $ldap->unbind; | |
| - | + | print "Done.\n"; | |
</pre> | </pre> | ||
Revision as of 08:53, 16 August 2011
The following script allows you to convert the mailboxes from a local Zarafa DB plugin to an Active Directory environment.
Requirements:
- Make sure all local Zarafa users are also available in the Active Directory
- Install the perl module MIME::Base64 and DBI
- Make sure you have a successful backup of the Zarafa database
Note: this is only possible with version before 6.30!
#!/usr/bin/perl -w
use strict;
use DBI;
use Net::LDAP;
sub readconfig($) {
my ($fn) = @_;
my %options;
open(CFG, $fn) or die("unable to open ".$fn." config file");
while (<CFG>) {
if ($_ =~ /^\s*[#!]/) {
next;
}
if ($_ =~ /^\s*(\S+)\s*=\s*([^\r]+)\r?$/) {
my $idx = $1;
my $val = $2;
chomp($val);
$val =~ s/\s+$//;
$options{$idx} = $val;
}
}
close(CFG);
return %options;
}
# @todo, differentiate between users/groups/etc.
sub get_extern_id($$$) {
my ($lo, $ldap, $db_username) = @_;
my $mesg = $ldap->search(filter => "($lo->{ldap_loginname_attribute}=$db_username)",
base => "$lo->{ldap_search_base}",
attrs => ["$lo->{ldap_loginname_attribute}", "$lo->{ldap_user_unique_attribute}"],
scope => "sub");
my @entries = $mesg->entries;
# if $mesg->count != 1 fallback on emailaddress lookup?
if ( $mesg->count == 0 ) {
print "Error updating $db_username. No entry found in ldap for ($lo->{ldap_loginname_attribute} = $db_username)\n";
return ($mesg->count, "");
}
if ( $mesg->count > 1 ) {
print "Error updating $db_username. Multiple entries found in ldap for ($lo->{ldap_loginname_attribute} = $db_username)\n";
return ($mesg->count, "");
}
return ($mesg->count, $entries[0]->get_value($lo->{ldap_user_unique_attribute}));
}
my $servercfg = $ARGV[0];
$servercfg = "/etc/zarafa/server.cfg" if (!defined($servercfg));
my %serveropt = readconfig($servercfg);
if (!defined($serveropt{user_plugin})) {
print "First argument must be the server configuration file\n";
exit(0);
}
if ($serveropt{user_plugin} ne "ldap") {
print "You only can change the unique attribute for the ldap user plugin, found: '".$serveropt{user_plugin}."'\n";
exit(0);
}
my %ldapopt = readconfig($serveropt{user_plugin_config});
my $ldapuri = $ldapopt{ldap_protocol}."://".$ldapopt{ldap_host}.":".$ldapopt{ldap_port};
my $ldap = Net::LDAP->new($ldapuri) or die ("LDAP connection failed");
my $msg = $ldap->bind($ldapopt{ldap_bind_user}, password => $ldapopt{ldap_bind_passwd});
$msg->code && die $msg->error;
my ($dbh, $query, $sth, $upd, $udh);
my @row;
$dbh = DBI->connect("dbi:mysql:database=".$serveropt{mysql_database}.";host=".$serveropt{mysql_host}, $serveropt{mysql_user}, $serveropt{mysql_password})
or die $DBI::errstr;
$query = "SELECT u.id AS user_id, op.value AS user_name, o.id FROM users AS u JOIN object AS o ON u.externid=o.externid JOIN objectproperty AS op ON o.id=op.objectid AND op.propname='loginname'";
$sth = $dbh->prepare($query) or die $DBI::errstr;
$sth->execute();
$dbh->begin_work();
$dbh->{AutoCommit} = 0;
while (@row = $sth->fetchrow_array) {
my $db_user_id = $row[0];
my $db_user_name = $row[1];
my $db_object_id = $row[2];
print "Found user '$db_user_name' in database with user_id '$db_user_id'\n";
my ($retval, $extern_id) = get_extern_id(\%ldapopt, $ldap, $db_user_name);
#print "$retval - $extern_id\n";
#print "$db_user_id - $db_user_name\n";
if ($retval == 1) {
$query = "UPDATE users SET externid=? WHERE id=?";
$upd = $dbh->prepare($query)
or die $DBI::errstr;
$upd->execute($extern_id, $db_user_id);
$query = "UPDATE object SET externid=? WHERE id=?";
$upd = $dbh->prepare($query)
or die $DBI::errstr;
$upd->execute($extern_id, $db_object_id);
}
}
print "Committing changes to database\n";
$dbh->commit();
$ldap->unbind;
print "Done.\n";