group.pm
branchfoerste
changeset 48 36aca6fb0ab8
parent 44 35441e1ae083
child 75 63b7c7fcd0cb
--- a/group.pm	Fri Nov 25 15:29:45 2011 +0100
+++ b/group.pm	Mon Nov 28 09:49:28 2011 +0100
@@ -1,4 +1,5 @@
 package group;
+
 # © Heiko Schlittermann
 # $Id$
 # $URL$
@@ -6,18 +7,18 @@
 use strict;
 use warnings;
 use Net::LDAP;
-use Net::LDAP::Constant qw(LDAP_ALREADY_EXISTS LDAP_NO_SUCH_OBJECT LDAP_TYPE_OR_VALUE_EXISTS);
+use Net::LDAP::Constant
+  qw(LDAP_ALREADY_EXISTS LDAP_NO_SUCH_OBJECT LDAP_TYPE_OR_VALUE_EXISTS);
 use Net::LDAP::Entry;
+
 #use Cyrus::IMAP::Admin;
 use Text::Wrap;
 use password;
 
-
 my $Cf;
-my ($ldap, $ubase, $abase, $gbase);
+my ( $ldap, $ubase, $abase, $gbase );
 my ($imap);
-END { $imap and $imap = undef; };
-
+END { $imap and $imap = undef; }
 
 sub _add();
 sub _list();
@@ -40,16 +41,16 @@
     $Cf = shift;
 
     require constant;
-    import constant OU_ACCOUNTS => $Cf->ldap_ou_accounts;
-    import constant OU_ALIASES => $Cf->ldap_ou_aliases;
-    import constant OU_GROUPS => $Cf->ldap_ou_groups;
-    import constant OC_RECIPIENT => $Cf->ldap_oc_recipient;
-    import constant OC_ACCESSGROUP => $Cf->ldap_oc_accessgroup;
-    import constant AT_PRIMARYADDRESS => $Cf->ldap_at_primaryaddress;
-    import constant AT_ADDRESS => $Cf->ldap_at_address;
-    import constant AT_GROUP => $Cf->ldap_at_group;
+    import constant OU_ACCOUNTS          => $Cf->ldap_ou_accounts;
+    import constant OU_ALIASES           => $Cf->ldap_ou_aliases;
+    import constant OU_GROUPS            => $Cf->ldap_ou_groups;
+    import constant OC_RECIPIENT         => $Cf->ldap_oc_recipient;
+    import constant OC_ACCESSGROUP       => $Cf->ldap_oc_accessgroup;
+    import constant AT_PRIMARYADDRESS    => $Cf->ldap_at_primaryaddress;
+    import constant AT_ADDRESS           => $Cf->ldap_at_address;
+    import constant AT_GROUP             => $Cf->ldap_at_group;
     import constant AT_FORWARDINGADDRESS => $Cf->ldap_at_forwardingaddress;
-    import constant AT_MEMBERUID => "memberUid";
+    import constant AT_MEMBERUID         => "memberUid";
 
     $gbase = OU_GROUPS . "," . $Cf->ldap_base;
     $ubase = OU_ACCOUNTS . "," . $Cf->ldap_base;
@@ -57,41 +58,46 @@
 }
 
 sub run($) {
+
     # Eigentlich brauchen wir für alles imap und ldap
     $ldap = new Net::LDAP $Cf->ldap_server or die;
-    my $r = $ldap->bind($Cf->ldap_bind_dn,
-	password => $Cf->ldap_password || $ENV{LDAP_PASS} || password::ask("LDAP (". $Cf->ldap_bind_dn .") password: "));
+    my $r = $ldap->bind( $Cf->ldap_bind_dn,
+             password => $Cf->ldap_password
+          || $ENV{LDAP_PASS}
+          || password::ask( "LDAP (" . $Cf->ldap_bind_dn . ") password: " ) );
     die $r->error, "\n" if $r->code;
 
     $imap = new Cyrus::IMAP::Admin or die $@;
-    $imap->authenticate(-server => $Cf->imap_server, -user => $Cf->imap_admin, 
-	-password => $Cf->imap_password || $ENV{IMAP_PASS} || password::ask("IMAP (". $Cf->imap_admin .") password: "))
-    or die $@;
-
+    $imap->authenticate(
+        -server   => $Cf->imap_server,
+        -user     => $Cf->imap_admin,
+        -password => $Cf->imap_password
+          || $ENV{IMAP_PASS}
+          || password::ask( "IMAP (" . $Cf->imap_admin . ") password: " )
+    ) or die $@;
 
-    if ($Cf->list) { _list() }
-    elsif ($Cf->add) { _add() }
-    elsif ($Cf->delete) { _delete() }
-    elsif ($Cf->modify) { _modify() }
-    else { die "Need action (--add|--modify|--list|--delete)\n" };
+    if    ( $Cf->list )   { _list() }
+    elsif ( $Cf->add )    { _add() }
+    elsif ( $Cf->delete ) { _delete() }
+    elsif ( $Cf->modify ) { _modify() }
+    else { die "Need action (--add|--modify|--list|--delete)\n" }
 
 }
 
 sub _add() {
-# Beim Hinzufügen tragen wir nur das unbedingt notwendige
-# ein.  Wenn es schon eine mailPrimaryAddress gibt oder eine
-# mail, machen wir gar nichts.
-# Ansonsten:
-# uid wird hinzugefügt
-# cn, sn bleiben unangetastet
-# Wenn die mailbox-Option gesetzt ist, wird die
-# IMAP-Mailbox angelegt.
 
+    # Beim Hinzufügen tragen wir nur das unbedingt notwendige
+    # ein.  Wenn es schon eine mailPrimaryAddress gibt oder eine
+    # mail, machen wir gar nichts.
+    # Ansonsten:
+    # uid wird hinzugefügt
+    # cn, sn bleiben unangetastet
+    # Wenn die mailbox-Option gesetzt ist, wird die
+    # IMAP-Mailbox angelegt.
 
     die "Need group name for creation\n" if not @ARGV;
     my $group = shift @ARGV;
-    my @members = split /,/, $Cf->members||"";
-
+    my @members = split /,/, $Cf->members || "";
 
     my $dn = "cn=$group,$gbase";
     my $r;
@@ -100,41 +106,50 @@
 
     verbose("\t$dn...");
 
-    $r = $ldap->search(base => $gbase, filter => "(cn=$group)");
+    $r = $ldap->search( base => $gbase, filter => "(cn=$group)" );
 
     die $r->error if $r->code;
     die "entries not expected" if $r->count > 1;
 
     my $e;
-    if ($r->count) {
-	$e = $r->shift_entry;
+    if ( $r->count ) {
+        $e = $r->shift_entry;
     } else {
-	$e = new Net::LDAP::Entry;
-	# Jetzt eine neue ID finden
-	foreach ($Cf->gid_min .. $Cf->gid_max) {
-	    # ist einfach eine lineare Suche, im Augenblick weiß ich nichts
-	    # clevereres
-	    my $r = $ldap->search(base => $gbase,
-		filter => "(gidNumber=$_)",
-		attrs => []);
-	    if ($r->count == 0) {
-		$e->add(gidNumber => $_);
-		last;
-	    }
-	}
-	$e->dn($dn);
-	$e->add(cn => $group);
+        $e = new Net::LDAP::Entry;
+
+        # Jetzt eine neue ID finden
+        foreach ( $Cf->gid_min .. $Cf->gid_max ) {
+
+            # ist einfach eine lineare Suche, im Augenblick weiß ich nichts
+            # clevereres
+            my $r = $ldap->search(
+                base   => $gbase,
+                filter => "(gidNumber=$_)",
+                attrs  => []
+            );
+            if ( $r->count == 0 ) {
+                $e->add( gidNumber => $_ );
+                last;
+            }
+        }
+        $e->dn($dn);
+        $e->add( cn => $group );
     }
 
-    grep /^CYRUS MAIL ACCESS GROUP/, $e->get("description") or $e->add(description => "CYRUS MAIL ACCESS GROUP");
+    grep /^CYRUS MAIL ACCESS GROUP/, $e->get("description")
+      or $e->add( description => "CYRUS MAIL ACCESS GROUP" );
 
-    if (defined $Cf->description) {
-	my @d = map { s/^(CYRUS MAIL ACCESS GROUP).*/"$1: ".$Cf->description/eg; $_ } $e->get("description");
-	$e->replace(description => \@d);
+    if ( defined $Cf->description ) {
+        my @d =
+          map { s/^(CYRUS MAIL ACCESS GROUP).*/"$1: ".$Cf->description/eg; $_ }
+          $e->get("description");
+        $e->replace( description => \@d );
     }
 
-    $e->replace(objectClass => [uniq $e->get("objectClass"), OC_ACCESSGROUP, "posixGroup"]);
-    $e->replace((AT_MEMBERUID) => [uniq $e->get(AT_MEMBERUID), @members]) if @members;
+    $e->replace( objectClass =>
+          [ uniq $e->get("objectClass"), OC_ACCESSGROUP, "posixGroup" ] );
+    $e->replace( (AT_MEMBERUID) => [ uniq $e->get(AT_MEMBERUID), @members ] )
+      if @members;
 
     $r = $e->update($ldap);
     die $r->error if $r->code;
@@ -144,122 +159,137 @@
 }
 
 sub _modify() {
-# Auch hier gehen wir davon aus, daß die dn direkt aus dem User-Namen folgt:
-# dn: uid=USER,...
+
+    # Auch hier gehen wir davon aus, daß die dn direkt aus dem User-Namen folgt:
+    # dn: uid=USER,...
     my (@groups) = @ARGV or die "Need groupname(s)\n";
 
-    my $r = $ldap->search(base => $gbase, 
-	filter => $_ = "(&(objectClass=".OC_ACCESSGROUP.")(|" . join("", map { "(cn=$_)" } @ARGV) . "))");
+    my $r = $ldap->search(
+        base   => $gbase,
+        filter => $_ =
+            "(&(objectClass="
+          . OC_ACCESSGROUP . ")(|"
+          . join( "", map { "(cn=$_)" } @ARGV ) . "))"
+    );
     die $r->error if $r->code;
     die "No entries found.\n" if $r->count == 0;
 
-    while (my $e = $r->shift_entry) {
-	my $r;
+    while ( my $e = $r->shift_entry ) {
+        my $r;
 
-	my $group = $e->get_value("cn");
-	my $dn = $e->dn;
+        my $group = $e->get_value("cn");
+        my $dn    = $e->dn;
 
-	my $modified = 0;
-	verbose "$group:";
+        my $modified = 0;
+        verbose "$group:";
 
-	verbose "\n\t$dn...";
+        verbose "\n\t$dn...";
 
-	if (defined $Cf->members) {
-	    my @m = split /,/, $Cf->members;
-	    grep { /^[+-]/ } @m or $e->delete(AT_MEMBERUID)
-		if $e->get_value(AT_MEMBERUID);
+        if ( defined $Cf->members ) {
+            my @m = split /,/, $Cf->members;
+            grep { /^[+-]/ } @m
+              or $e->delete(AT_MEMBERUID)
+              if $e->get_value(AT_MEMBERUID);
 
-	    foreach my $m (@m) {
-		if ($m =~ s/^-//) {
-		    $e->delete((AT_MEMBERUID) => [$m])
-		} else {
-		    $m =~ s/^\+//;
-		    $e->add((AT_MEMBERUID) => [$m])
-		}
-	    }
-	    $modified++;
-	}
+            foreach my $m (@m) {
+                if ( $m =~ s/^-// ) {
+                    $e->delete( (AT_MEMBERUID) => [$m] );
+                } else {
+                    $m =~ s/^\+//;
+                    $e->add( (AT_MEMBERUID) => [$m] );
+                }
+            }
+            $modified++;
+        }
 
-	if (defined $Cf->description) {
-	    my @d = map { s/^(CYRUS MAIL ACCESS GROUP).*/"$1: ".$Cf->description/eg; $_ } $e->get("description");
-	    $e->replace(description => \@d);
-	    $modified++;
-	}
-
-	$e->dump if $Cf->debug;
+        if ( defined $Cf->description ) {
+            my @d = map {
+                s/^(CYRUS MAIL ACCESS GROUP).*/"$1: ".$Cf->description/eg;
+                $_
+            } $e->get("description");
+            $e->replace( description => \@d );
+            $modified++;
+        }
 
-	if ($modified) {
-	    $r = $e->update($ldap);
-	    die $r->error.$r->code if $r->code;
-	}
+        $e->dump if $Cf->debug;
 
-	verbose "ok\n";
+        if ($modified) {
+            $r = $e->update($ldap);
+            die $r->error . $r->code if $r->code;
+        }
 
-	print "\n";
+        verbose "ok\n";
+
+        print "\n";
     }
 }
 
 sub _delete() {
-# Wir gehen davon aus, daß es einen dn uid=USER,ou=.... gibt, den wir löschen können.
-# Wir löschen den kompletten Container.  Es kann natürlich sein, daß er noch jemand anders gehört.  
-# Dann ist das Pech.  Um es besser zu haben, müßten wir für alles unsere eigenen
-# Objektklassen haben...
 
-    if (!@ARGV) {
-	print "Group: ";
-	chomp($_ = <>);
-	@ARGV = ($_);
+    # Wir gehen davon aus, daß es einen dn uid=USER,ou=.... gibt, den wir löschen können.
+    # Wir löschen den kompletten Container.  Es kann natürlich sein, daß er noch jemand anders gehört.
+    # Dann ist das Pech.  Um es besser zu haben, müßten wir für alles unsere eigenen
+    # Objektklassen haben...
+
+    if ( !@ARGV ) {
+        print "Group: ";
+        chomp( $_ = <> );
+        @ARGV = ($_);
     }
 
     #my $filter = "(&((cn=%s)(objectClass=".OC_ACCESSGROUP.")))";
 
-    my $r = $ldap->search(base => $gbase,
-	filter => "(&(objectClass=".OC_ACCESSGROUP.")(|" . join("", map { "(cn=$_)" } @ARGV) . "))",
-	attrs => [AT_MEMBERUID, "cn"]); 
+    my $r = $ldap->search(
+        base   => $gbase,
+        filter => "(&(objectClass="
+          . OC_ACCESSGROUP . ")(|"
+          . join( "", map { "(cn=$_)" } @ARGV ) . "))",
+        attrs => [ AT_MEMBERUID, "cn" ]
+    );
 
-    if ($r->count == 0) {
-	verbose "No objects found\n";
-	return;
+    if ( $r->count == 0 ) {
+        verbose "No objects found\n";
+        return;
     }
 
-    while (my $e = $r->shift_entry) {
-	my $dn = $e->dn;
-	verbose $dn;
-	my $r = $ldap->delete($dn);
+    while ( my $e = $r->shift_entry ) {
+        my $dn = $e->dn;
+        verbose $dn;
+        my $r = $ldap->delete($dn);
 
-	if ($r->code == LDAP_NO_SUCH_OBJECT) {
-	    verbose("doesn't exist");
-	} elsif ($r->code == 0) {
-	    verbose(" ok");
-	} else {
-	    die $r->error;
-	}
-	verbose("\n");
+        if ( $r->code == LDAP_NO_SUCH_OBJECT ) {
+            verbose("doesn't exist");
+        } elsif ( $r->code == 0 ) {
+            verbose(" ok");
+        } else {
+            die $r->error;
+        }
+        verbose("\n");
     }
 }
 
 sub _list() {
     my $filter;
     @ARGV = ("*") unless @ARGV;
+
     #$filter = "(|" . join("", map { "(uid=$_)" } @ARGV) . ")";
-    $filter = "(objectClass=".OC_ACCESSGROUP.")";
+    $filter = "(objectClass=" . OC_ACCESSGROUP . ")";
 
     my $r = $ldap->search(
-	filter => $filter,
-	base => $gbase,
-	attrs => [AT_MEMBERUID, qw/cn description/],
+        filter => $filter,
+        base   => $gbase,
+        attrs  => [ AT_MEMBERUID, qw/cn description/ ],
     );
     die $r->error if $r->code;
 
+    while ( my $e = $r->shift_entry ) {
+        my $cn    = $e->get_value("cn");
+        my $descr = $e->get_value("description");
+        my @uids  = $e->get_value(AT_MEMBERUID);
 
-    while (my $e = $r->shift_entry) {
-	my $cn = $e->get_value("cn");
-	my $descr = $e->get_value("description");
-	my @uids = $e->get_value(AT_MEMBERUID);
-
-	print "$cn: ($descr)\n";
-	print "\t", join "\n\t", @uids;
-	print "\n";
+        print "$cn: ($descr)\n";
+        print "\t", join "\n\t", @uids;
+        print "\n";
     }
 }
 
@@ -273,19 +303,23 @@
     return keys %x;
 }
 
-{   my @pw;
-sub _mkpw($) {
-    my $in = $_[0];
+{
+    my @pw;
 
-    return $in unless $in and $in eq "{pwgen}";
+    sub _mkpw($) {
+        my $in = $_[0];
+
+        return $in unless $in and $in eq "{pwgen}";
 
-    if (!@pw) {
-	chomp(@pw = `pwgen 8 10 2>/dev/null|| mkpasswd`);
-	die "pwgen/mkpasswd: $!" if $?;
+        if ( !@pw ) {
+            chomp( @pw = `pwgen 8 10 2>/dev/null|| mkpasswd` );
+            die "pwgen/mkpasswd: $!" if $?;
+        }
+        return shift @pw;
+
     }
-    return shift @pw;
-    
-} }
+}
 
 1;
+
 # vim:sts=4 sw=4 aw ai sm nohlsearch: