--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile Fri Feb 01 10:07:44 2008 +0000
@@ -0,0 +1,7 @@
+SCRIPT = update-mailboxes
+
+.PHONLY: all install
+
+all:
+install:
+ install -m0755 ${SCRIPT} /usr/local/sbin/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/update-mailboxes Fri Feb 01 10:07:44 2008 +0000
@@ -0,0 +1,171 @@
+#! /usr/bin/perl
+# Dieser Script legt einfach die Mailboxen an, die der LDAP/AD-Server
+# kennt. Wenn die Mailbox schon existieren sollte, passiert einfach gar nichts.
+# © 2008 Heiko Schlittermann
+use strict;
+use warnings;
+use File::Basename;
+use Fatal qw(open);
+use Mail::IMAPClient;
+use Net::LDAP;
+use Getopt::Long;
+use Pod::Usage;
+use if $ENV{DEBUG} => "Smart::Comments";
+
+my $ME = basename $0;
+my $PRIVATE = "$ENV{HOME}/private/accounts";
+my $LDAPCONF = "/etc/ldap/ldap.conf";
+my $SERVER = "localhost";
+
+my $opt_delete = 0;
+my $opt_help = 0;
+my $opt_man = 0;
+my $opt_verbose = -t STDOUT;
+
+# USER und PASS kommen aus ~/private/accounts
+my ($USER, $PASS);
+{
+ open(my $priv, $PRIVATE);
+ chomp(
+ (undef, $USER, $PASS) = split /\s*:\s*/,
+ (grep /^cyrusadmin\s*:/, <$priv>)[0]
+ );
+}
+
+my ($LDAPADMIN, $LDAPPASS);
+{
+ open(my $priv, $PRIVATE);
+ chomp(
+ (undef, $LDAPADMIN, $LDAPPASS) = split /\s*:\s*/,
+ (grep /^ldapadmin\s*:/, <$priv>)[0]
+ );
+}
+
+my ($LDAPBASE, $LDAPSERVER);
+{
+ open(my $in, $LDAPCONF);
+ $_ = join "", <$in>;
+ ($LDAPBASE) = /^\s*BASE\s+(.*?)\s*$/ms;
+ ($LDAPSERVER) = /^\s*URI\s+(.*?)\s*$/ms;
+ $LDAPBASE = "ou=proconcept,$LDAPBASE";
+}
+
+MAIN: {
+ Getopt::Long::Configure("bundling");
+ GetOptions(
+ "d|delete" => \$opt_delete,
+ "v|verbose!" => \$opt_verbose,
+ "man" => \$opt_man,
+ "help" => \$opt_help,
+ ) or pod2usage();
+
+ pod2usage(-exitval => 0, -verbose => 3) if $opt_man;
+ pod2usage(-exitval => 0, -verbose => 1) if $opt_help;
+
+ $opt_verbose and $| = 1
+ or open(STDOUT, ">/dev/null");
+
+ # IMAP anzapfen
+ my $imap = new Mail::IMAPClient(
+ Server => $SERVER,
+ User => $USER,
+ Password => $PASS
+ ) or die "Can't connect: $!\n";
+
+ my %folder = map { $_, 1 } grep !m{/.*/}, $imap->folders();
+
+ # LDAP anzapfen
+ my $ldap = new Net::LDAP($LDAPSERVER, onerror => "die");
+ $ldap->bind($LDAPADMIN, password => $LDAPPASS);
+ my $msg = $ldap->search(
+ base => $LDAPBASE,
+ filter => "(&(samAccountName=*))",
+ attrs => ["samAccountName"],
+ );
+ die "$ME: keine LDAP-Einträge gefunden\n" if $msg->count == 0;
+
+ while (my $e = $msg->pop_entry) {
+
+ my $folder = "user/" . $e->get_value("samAccountName");
+ delete $folder{$folder};
+
+ print "$folder: ";
+ print "exists\n" and next if $imap->exists($folder);
+
+ print "creating ";
+ $imap->create($folder)
+ or warn "$folder: $@\n"
+ and next;
+ print "acl ";
+ $imap->setacl($folder, $USER, "lrswipcda")
+ or warn "$folder: $@\n"
+ and next;
+
+ print "ok\n";
+ }
+
+ if (keys %folder) {
+ print scalar(keys %folder)
+ . " unused mailboxe(s):\n" . "\t"
+ . join("\n\t", keys %folder) . "\n";
+
+ if ($opt_delete) {
+ print "deleting unused mailboxes\n";
+ foreach (keys %folder) {
+ print "$_ ";
+ $imap->delete($_) and print "ok\n"
+ or warn "$_: ($@)\n";
+ }
+ }
+ }
+
+ 0;
+}
+
+__END__
+
+=head1 NAME
+
+update-mailboxes - Cyrus-Mailboxen entsprechend ADS anlegen
+
+=head1 SYNOPSIS
+
+ update-mailboxes [-v|--[no]verbose] [-d|--delete]
+ update-mailboxes --help | --man
+
+=head1 DESCRIPTION
+
+Mit B<update-mailboxes> werden die Mailnutzer aus dem ADS des Domaincontrollers
+ausgelesen und für jeden dieser Nutzer wird eine Cyrus-Mailbox angelegt.
+
+Ist diese Mailbox schon vorhanden, passiert nichts.
+
+Die Mailboxen werden so angelegt, daß der Cyrus-Admin Vollzugriff hat.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-v>|B<--[no]verbose>
+
+Etwas mehr Gesprächigkeit. (default: 1, wenn STDOUT ein TTY ist, sonst 0)
+
+=item B<-d>|B<--delete>
+
+Löscht Mailboxen, die dem ADS nicht bekannt sind. (default: 0)
+
+=item B<--help> | B<--man>
+
+Dokumentation.
+
+=back
+
+=head1 AUTHOR
+
+Heiko Schlittermann
+
+=head1 SEE ALSO
+
+L<cyradm(1)> L<ldapsearch(1)>
+
+=cut