--- a/update-mailboxes Fri Apr 18 08:48:10 2008 +0000
+++ b/update-mailboxes Tue May 06 12:26:07 2008 +0000
@@ -12,58 +12,66 @@
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 $ME = basename $0;
+my $PRIVATE = "$ENV{HOME}/private/accounts";
+my $LDAPCONF = "/etc/ldap/ldap.conf";
+my $SERVER = "localhost";
my $BLACKLIST = "/etc/mail/update-mailboxes.blacklist";
+my $OULIST = "/etc/mail/update-mailboxes.oulist";
-my $opt_delete = 0;
-my $opt_protocol= undef;
-my $opt_help = 0;
-my $opt_man = 0;
-my $opt_verbose = -t STDOUT;
-
+my $opt_delete = 0;
+my $opt_protocol = undef;
+my $opt_help = 0;
+my $opt_man = 0;
+my $opt_verbose = -t STDOUT;
+my $opt_dry = 0;
sub get_credentials($$);
-my ($USER, $PASS) = get_credentials($PRIVATE => "cyrusadmin");
-my ($LDAPADMIN, $LDAPPASS) = get_credentials($PRIVATE => "ldapadmin");
+my ( $USER, $PASS ) = get_credentials( $PRIVATE => "cyrusadmin" );
+my ( $LDAPADMIN, $LDAPPASS ) = get_credentials( $PRIVATE => "ldapadmin" );
-my ($LDAPBASE, $LDAPSERVER);
+my ( $LDAPBASE, $LDAPSERVER );
{
- open(my $in, $LDAPCONF);
+ open( my $in, $LDAPCONF );
$_ = join "", <$in>;
($LDAPBASE) = /^\s*BASE\s+(.*?)\s*$/ms;
($LDAPSERVER) = /^\s*URI\s+(.*?)\s*$/ms;
- $LDAPBASE = "ou=proconcept,$LDAPBASE";
+}
+
+my @OU;
+{
+ open( my $in, $OULIST );
+ @OU = grep /^(?!#)\S+/, map { /(\S+)/; $1 } <$in>;
}
my %BLACK;
-if (open(my $in, $BLACKLIST)) {
- while (<$in>) { chomp;
- s/#.*//;
- s/^\s*(.*)\s*$/$1/;
- next if not $_;
- $BLACK{$_} = 1;
- }
+if ( open( my $in, $BLACKLIST ) ) {
+ while (<$in>) {
+ chomp;
+ s/#.*//;
+ s/^\s*(.*)\s*$/$1/;
+ next if not $_;
+ $BLACK{$_} = 1;
+ }
}
MAIN: {
Getopt::Long::Configure("bundling");
GetOptions(
- "p|protocol=s" => \$opt_protocol,
- "d|delete" => \$opt_delete,
- "v|verbose!" => \$opt_verbose,
- "man" => \$opt_man,
- "help" => \$opt_help,
+ "p|protocol=s" => \$opt_protocol,
+ "d|delete" => \$opt_delete,
+ "v|verbose!" => \$opt_verbose,
+ "n|dry!" => \$opt_dry,
+ "man" => \$opt_man,
+ "help" => \$opt_help,
) or pod2usage();
- pod2usage(-exitval => 0, -verbose => 3) if $opt_man;
- pod2usage(-exitval => 0, -verbose => 1) if $opt_help;
+ 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");
+ or open( STDOUT, ">/dev/null" );
# IMAP anzapfen
my $imap = new Mail::IMAPClient(
@@ -74,94 +82,112 @@
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;
+ # LDAP anzapfen und erstmal die Einträge sammeln (ist notwendig,
+ # weil wir jetzt mehrere Gruppen haben und der ADS leider nicht
+ # (ou:dn:=*) versteht
+
+ my @entries;
+ {
+ my $ldap = new Net::LDAP( $LDAPSERVER, onerror => "die" );
+ $ldap->bind( $LDAPADMIN, password => $LDAPPASS );
+ foreach my $ou (@OU) {
+ my $msg = $ldap->search(
+ base => "$ou,$LDAPBASE",
+ filter => "(&(samAccountName=*))",
+ attrs => ["samAccountName"],
+ );
+ push @entries, $msg->entries;
+ }
+
+ }
+ die "$ME: keine LDAP-Einträge gefunden\n" if not @entries;
my %mbox;
- while (my $e = $msg->pop_entry) {
+ foreach my $e (@entries) {
+
+ my $mbox = $e->get_value("samAccountName");
- my $mbox = $e->get_value("samAccountName");
-
- if ($BLACK{$mbox}) {
- print "$mbox blacklisted\n";
- next;
- }
+ if ( $BLACK{$mbox} ) {
+ print "$mbox blacklisted\n";
+ next;
+ }
my $folder = "user/$mbox";
print "$folder: ";
- if ($imap->exists($folder)) {
- print "exists\n";
- $mbox{$mbox} = $folder;
- next;
- }
+
+ if ( $imap->exists($folder) ) {
+ print "exists\n";
+ $mbox{$mbox} = $folder;
+ next;
+ }
+
+ if ($opt_dry) {
+ $mbox{$mbox} = $folder;
+ print " doing nothing (dry run)\n";
+ next;
+ }
print "creating ";
- if (!$imap->create($folder)) {
- warn "$folder: $@\n";
- next;
- }
+ if ( !$imap->create($folder) ) {
+ warn "$folder: $@\n";
+ next;
+ }
- $mbox{$mbox} = $folder;
+ $mbox{$mbox} = $folder;
print "acl ";
- if (!$imap->setacl($folder, $USER, "lrswipcda")) {
- warn "$folder: $@\n";
- next;
- }
+ if ( !$imap->setacl( $folder, $USER, "lrswipcda" ) ) {
+ warn "$folder: $@\n";
+ next;
+ }
print "ok\n";
}
- delete @folder{values %mbox};
+ delete @folder{ values %mbox };
# now check if there are still folders we didn't touch;
- delete @folder{map { "user/$_" } keys %mbox};
+ delete @folder{ map { "user/$_" } keys %mbox };
- if (keys %folder) {
- print scalar(keys %folder)
+ if ( keys %folder ) {
+ print scalar( keys %folder )
. " unused mailboxe(s):\n" . "\t"
- . join("\n\t", keys %folder) . "\n";
+ . join( "\n\t", keys %folder ) . "\n";
- if ($opt_delete) {
+ if ($opt_delete && $opt_dry == 0) {
print "deleting unused mailboxes\n";
- foreach (keys %folder) {
+ foreach ( keys %folder ) {
print "$_ ";
$imap->delete($_) and print "ok\n"
or warn "$_: ($@)\n";
}
}
- else {
- %mbox = (%mbox, %folder);
- }
+ else {
+ %mbox = ( %mbox, %folder );
+ }
}
if ($opt_protocol) {
- open(my $o, ">$opt_protocol") or die "Can't open >$opt_protocol: $!\n";
- print $o join "\n",
- "# Liste der Mailboxen (nur zur Info)",
- "# updater: $0 " . '($Id$)',
- sort(keys %mbox),
- "";
+ open( my $o, ">$opt_protocol" )
+ or die "Can't open >$opt_protocol: $!\n";
+ print $o join "\n", "# Liste der Mailboxen (nur zur Info)",
+ "# updater: $0 "
+ . '($Id$)',
+ sort( keys %mbox ), "";
}
exit 0;
}
sub get_credentials($$) {
- my ($file, $pattern) = @_;
- open(my $fh, $file) or die "Can't open $file: $!\n";
- my (undef, $u, $p) = (split /\s*:\s*/, (grep /^$pattern\s*:/, <$fh>)[0]);
- chomp($u, $p);
- return($u, $p);
+ my ( $file, $pattern ) = @_;
+ open( my $fh, $file ) or die "Can't open $file: $!\n";
+ my ( undef, $u, $p ) =
+ ( split /\s*:\s*/, ( grep /^$pattern\s*:/, <$fh> )[0] );
+ chomp( $u, $p );
+ return ( $u, $p );
}
__END__