aboutsummaryrefslogtreecommitdiffstats
path: root/ldap/obsolete
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem.moulin@fripost.org>2012-08-20 01:54:17 +0200
committerGuilhem Moulin <guilhem.moulin@fripost.org>2012-08-20 01:54:17 +0200
commitb6762006da16052ed0b55e91b9416712efca01ca (patch)
tree3b3db4c8f749a2594eff88c3c23fd6a50623479f /ldap/obsolete
parentded29bf9eb3fa40c56eb9ace365d13e6348e215c (diff)
Archive the MySQL -> LDAP migration procedure.
Diffstat (limited to 'ldap/obsolete')
-rwxr-xr-xldap/obsolete/addadmin.pl51
-rw-r--r--ldap/obsolete/ldap-migrate71
-rwxr-xr-xldap/obsolete/ldap-migrate.pl180
3 files changed, 302 insertions, 0 deletions
diff --git a/ldap/obsolete/addadmin.pl b/ldap/obsolete/addadmin.pl
new file mode 100755
index 0000000..508d100
--- /dev/null
+++ b/ldap/obsolete/addadmin.pl
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+
+# Run `sudo ./addadmin.pl' to add yourself as an administrator for virtual
+# mail hosting.
+# (Use the optional argument if you're not happy with your login name.)
+#
+# To use the tools, you'll need to edit `~/.fripost.yml' and replace
+# `bind_dn' and `bind_pw' by, respectively, the returned Distinguished Name
+# and your password
+
+use 5.010_000;
+use strict;
+use warnings;
+use utf8;
+
+use FindBin qw($Bin);
+use lib "$Bin/lib";
+
+use Fripost::Schema;
+use Fripost::Password;
+use Fripost::Prompt;
+use YAML::Syck;
+
+my $user = $ARGV[0];
+$user //= $ENV{SUDO_USER};
+$user //= $ENV{USER};
+
+die "Error: Cannot find user name.\n"
+ unless defined $user;
+
+# Connect to the LDAP server
+my $ldapconf = LoadFile ( 'ldap.yml' );
+my $ldap = Fripost::Schema->new( $ldapconf );
+$ldap = $ldap->{_ldap};
+
+
+my $dn = join ',', ( 'cn='.$user
+ , 'ou=managers'
+ , (split ',', $ldapconf->{base_dn},2)[1] );
+
+my $password = hash( undef, undef, prompt_password() );
+my $res = $ldap->add( $dn,
+ attrs => [ objectClass => [ 'simpleSecurityObject'
+ , 'organizationalRole' ]
+ , userPassword => $password
+ ]
+ );
+ die "Error: " .$res->error. "\n" if $res->code;
+
+say $dn;
+$ldap->unbind();
diff --git a/ldap/obsolete/ldap-migrate b/ldap/obsolete/ldap-migrate
new file mode 100644
index 0000000..123dbe9
--- /dev/null
+++ b/ldap/obsolete/ldap-migrate
@@ -0,0 +1,71 @@
+/*********************************************************************/
+/* Migration plan, to replace the MySQL database by a LDAP directory */
+/* structure (for virtual e-mail hosting). */
+/*********************************************************************/
+
+ * First we should stop to welcome new members for a little while.
+
+ * Then someone should run the following on mistral:
+ cd /etc/ldap/fripost/migration/ && sudo ./ldap-migrate.pl
+That will populate the base directory with what is in the MySQL
+database.
+A log file, `fripost-migration-$$.log' (where `$$' is the PID of the
+running process) will be created. One should read it, check the
+warning/errors (prefixed with `WARN:' or `Error:') and fix them if
+needed.
+Note: The new entries will be created by the DN
+"cn=migrator,ou=managers,...", created specialy for this purpose. Also,
+creation and modification timestamps will be reset.
+
+ * On each of the MX's, Postfix' configuration should be updated with LDAP
+lookup configuration files, which are currently in
+`/etc/ldap/fripost/ldap_*.cf'.
+Test the Postfix configuration:
+ - Send to at least one mailbox and one alias, check the logs to verify
+that emails are delivered.
+ - Send a mail to fake@fripost.org (or run `sendmail -bv fake@fripost.org')
+and ensure that Postfix answers with "User unknown in virtual mailbox table (in
+reply to RCPT TO command)".
+
+ * On mistral, Dovecot configuration should be updated as written in
+`fripost-docs.org'.
+Test Dovecot: Is it possible to login? Is it possible to browse the IMAP
+directory?
+ openssl s_client -connect imap.fripost.org:993 -CApath /etc/ssl/certs/
+ 1 login user@fripost.org password
+ 2 list "" "*"
+ 3 logout
+
+ * Shut down MySQL.
+
+ * In git's repository for `fripost-tools' merge the `ldap' branch in
+`master'.
+
+ * Remove the DN "cn=migrator,ou=managers,...", and restrict the
+ACL for the managers to be allowed to write on "ou=virtual,..." only.
+
+ * Wait for a week or two.
+
+ * Dump the MySQL database and save it somewhere? Anyways, then remove
+MySQL from hosts.
+
+
+
+/*********************************************************************/
+/* Note for the admins. */
+
+To use the new `fripost-tools', you need to have an entry under
+`ou=managers,...'. To add yourself as a manager, run the following on
+mistral:
+ cd /etc/ldap/fripost/migration/ && sudo ./addadmin.pl
+
+ * (Use the optional argument if you're not happy with your login name.)
+
+ * (If you choose to randomly generate your password, beware that it will
+only be 20 characters long.)
+
+ * You'll then need to chmod 600 and create/edit `~/.fripost.yml' on the
+machine you plan to use the tools on (a template can be found in the
+git repository), and replace `bind_dn' and `bind_pw' by, respectively,
+the returned Distinguished Name and your password.
+
diff --git a/ldap/obsolete/ldap-migrate.pl b/ldap/obsolete/ldap-migrate.pl
new file mode 100755
index 0000000..d8af8ca
--- /dev/null
+++ b/ldap/obsolete/ldap-migrate.pl
@@ -0,0 +1,180 @@
+#!/usr/bin/perl
+
+#######################################################################
+# Migration from MySQL to LDAP. #
+#######################################################################
+
+# This file depends on the LDAP version of Fripost::Schema.
+# (git checkout ldap)
+#
+# It reads LDAP's configuration from `./ldap.yml', and the MySQL
+# configuration from `./dbh.yml'. (The MySQL configuration is the old
+# configuration (default.yml) that was read by the vanilla fripost-tools
+# (from the master branch).
+#
+# Set the flag `--pretend' to only simulate the migration.
+# REMARK: The migration has not been tested yet!
+#
+# The changes and warnings are dumped both into the standard error, and
+# into a log file "fripost-migration-$$.log", where "$$" is the current
+# PID.
+#
+# REMARK: the columns `create_date' and `change_date' are ignored
+# (reseted, actually), since the corresponding LDAP attributes are set
+# by the server and there is no way for the client to force their value.
+#
+# Some other columns may be ignored during the migration (e.g.,
+# `domain.description' if it does not have the right form), but the
+# program is supposed to say so.
+#
+# REMARK: The columns `alias.domain', and `mailbox.domain' are not in
+# the LDAP schema.
+
+use 5.010_000;
+use strict;
+use warnings;
+use utf8;
+
+use FindBin qw($Bin);
+use lib "$Bin/lib";
+
+use Fripost::Schema;
+use DBI;
+use Getopt::Long;
+use YAML::Syck;
+
+my $pretend = 0;
+GetOptions( 'pretend' => \$pretend );
+
+
+# Connect to the LDAP server
+my $ldapconf = LoadFile ( 'ldap.yml' );
+my $ldap = Fripost::Schema->new( $ldapconf );
+
+
+# Connection to the MySQL sever
+my $dbhconf = LoadFile ( 'dbh.yml' );
+my $dbh = DBI->connect( $dbhconf->{dbi_dsn}, $dbhconf->{admuser}, $dbhconf->{admpass} );
+$dbh->do( "SET NAMES UTF8" ) or die "Error: Can't set names to UTF-8.\n";
+
+# Log the inserts and errors.
+open LOG, '>', "fripost-migration-$$.log" or die $!;
+
+
+# Migrate domains
+{
+ my $rs = $dbh->selectall_hashref( "SELECT * FROM domain", 'domain' )
+ or die "Can't select: $!\n";
+ foreach my $domainname (keys %$rs) {
+ my $domain = $rs->{$domainname};
+ if ($ldap->domain->search({ domain => $domainname })->count) {
+ &mesg ("WARN: Skipping domain `$domainname': Already exists.\n");
+ next;
+ }
+ my $mesg = "Inserting domain `$domainname'";
+ if (defined $domain->{description} and $domain->{description} ne '') {
+ my $owner = $domain->{description};
+ if ($ldap->user->search({ domain => (split/\@/, $owner, 2)[1] })->count
+ && $ldap->user->search({ username => $owner })->count) {
+ $mesg .= " (for owner `$owner')"
+ }
+ else {
+ &mesg ("WARN: Skipping ownership of `$domainname': Unknown owner `$owner'.\n");
+ delete $domain->{description};
+ }
+ }
+ else {
+ delete $domain->{description} if exists $domain->{description};
+ }
+ &mesg ($mesg ."... ");
+ $ldap->domain->add({ domain => $domainname
+ , owner => $domain->{description}
+ , isActive => &isActive($domain)
+ })
+ unless $pretend;
+ &mesg ("Done.\n");
+ }
+}
+&mesg ("\n================================\n\n");
+
+
+# Migrate mailboxes
+{
+ my $rs = $dbh->selectall_hashref( "SELECT * FROM mailbox", 'username' )
+ or die "Can't select: $!\n";
+ foreach my $username (keys %$rs) {
+ my $user = $rs->{$username};
+ unless ($ldap->domain->search({ domain => (split/\@/, $username, 2)[1] })->count) {
+ &mesg ("WARN: Skipping user `$username': Unknown domain.\n");
+ next;
+ }
+ if ($ldap->user->search({ username => $username })->count) {
+ &mesg ("WARN: Skipping user `$username': Already exists.\n");
+ next;
+ }
+ &mesg ("WARN: Ignoring user name `$user->{name}'")
+ if defined $user->{name} and $user->{name} ne '';
+ &mesg ("Inserting user `$username'... ");
+ $ldap->user->add({ username => $username
+ , userPassword => $user->{password}
+ , maildir => $user->{maildir}
+ , isActive => &isActive($user)
+ })
+ unless $pretend;
+ &mesg ("Done.\n");
+ }
+}
+&mesg ("\n================================\n\n");
+
+
+# Migrate aliases
+{
+ my $rs = $dbh->selectall_hashref( "SELECT * FROM alias", 'address' )
+ or die "Can't select: $!\n";
+ foreach my $address (keys %$rs) {
+ unless ($ldap->domain->search({ domain => (split/\@/, $address, 2)[1] })->count) {
+ &mesg ("WARN: Skipping alias `$address': Unknown domain.\n");
+ next;
+ }
+
+ my $alias = $rs->{$address};
+ if ($ldap->alias->search({ address => $address })->count) {
+ &mesg ("WARN: Skipping alias `$address': Already exists.\n");
+ next;
+ }
+ my @goto = split /, */, $alias->{goto};
+ unless ($#goto >= 0) {
+ &mesg ("WARN: Skipping alias `$address': Empty goto.\n");
+ next;
+ }
+
+ foreach my $goto (@goto) {
+ &mesg ("Inserting alias `$address' -> `$goto'... ");
+ $ldap->alias->add({ address => $address
+ , goto => $goto
+ , isActive => &isActive($alias)
+ })
+ unless $pretend;
+ &mesg ("Done.\n");
+ }
+ }
+}
+&mesg ("\n================================\n\n");
+
+
+# Disconnect
+$dbh->disconnect();
+$ldap->unbind();
+close LOG;
+
+sub mesg {
+ print STDERR @_;
+ print LOG @_;
+}
+
+sub isActive {
+ if ($_[0]->{active}) {
+ return 'TRUE';
+ }
+ return 'FALSE';
+}