account.pm.rej
branchfoerste-cms
changeset 72 66bf85163780
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/account.pm.rej	Fri Feb 21 11:56:39 2014 +0100
@@ -0,0 +1,530 @@
+--- account.pm	Mon Mar 02 13:51:24 2009 +0000
++++ account.pm	Thu Dec 15 16:08:16 2011 +0100
+@@ -118,257 +129,342 @@
+ 
+     verbose("\t$dn...");
+ 
+-    $r = $ldap->search(base => $ubase, filter => "(uid=$user)");
++    $r = $ldap->search( base => $ubase, filter => "(uid=$user)" );
+     die $r->error if $r->code;
+     die "Multiple 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;
+-	$e->dn($dn);
++        $e = new Net::LDAP::Entry;
++        $e->dn($dn);
+     }
+ 
+-    if ($e->exists("mail") || $e->exists(AT_PRIMARYADDRESS) || $e->exists("userPassword")) {
+-	verbose "exists\n";
++    if (   $e->exists("mail")
++        || $e->exists(AT_PRIMARYADDRESS)
++        || $e->exists("userPassword") )
++    {
++        verbose "exists\n";
+     } else {
+-    FORCE:
++      FORCE:
+ 
+-	# Bevor wir ans Werk gehen, noch ein paar Tests (mailPrimaryAddress und mail darf
+-	# noch nicht vergeben sein)
+-	foreach my $a ($mailPrimaryAddress, @$mailAddress) {
+-	    $a =~ s/!$// and next;   # wenn ein ! am Ende steht, dann ist es so gewollt und wird
+-				     # nicht geprüft
+-	    $r = $ldap->search(filter => "(mail=$a)", base => $ubase);
+-	    die $r->error if $r->code;
+-	    die "$a ist schon vergeben\n" if $r->count;
+-	}
++        # Bevor wir ans Werk gehen, noch ein paar Tests (mailPrimaryAddress und mail darf
++        # noch nicht vergeben sein)
++        foreach my $a ( $mailPrimaryAddress, @$mailAddress ) {
++            $a =~ s/!$//
++              and
++              next;  # wenn ein ! am Ende steht, dann ist es so gewollt und wird
++                     # nicht geprüft
++            $r = $ldap->search( filter => "(mail=$a)", base => $ubase );
++            die $r->error if $r->code;
++            die "$a ist schon vergeben\n" if $r->count;
++        }
+ 
+-	$e->replace(objectClass => [uniq $e->get("objectClass"), qw/uidObject person/, OC_RECIPIENT]);
+-	$e->replace(uid => [uniq $e->get("uid"), $user]);
++        $e->replace(
++            objectClass => [
++                uniq $e->get("objectClass"),
++                qw/uidObject person/,
++                OC_RECIPIENT
++            ]
++        );
++        $e->replace( uid => [ uniq $e->get("uid"), $user ] );
+ 
+-	$e->add((AT_ADDRESS) => $mailAddress);
+-	$e->add((AT_PRIMARYADDRESS) => $mailPrimaryAddress);
+-	$e->add(userPassword => $pw);
+-	$e->add((AT_GROUP) => $mailGroup) if @$mailGroup;
+-	$e->add((AT_FORWARDINGADDRESS) => $mailForwardingAddress) if @$mailForwardingAddress;
++        $e->add( (AT_ADDRESS)        => $mailAddress );
++        $e->add( (AT_PRIMARYADDRESS) => $mailPrimaryAddress );
++        $e->add( userPassword => "{plain}$pw" );
++        $e->add( (AT_GROUP) => $mailGroup ) if @$mailGroup;
++        $e->add( (AT_FORWARDINGADDRESS) => $mailForwardingAddress )
++          if @$mailForwardingAddress;
++        $e->add( (AT_QUOTA) => $Cf->imap_quota );
++        $e->add( (AT_ACLGROUPS) => $Cf->imap_aclgroups ) if $Cf->imap_aclgroups;
+ 
+-	# $e->add(iusRestrictedMail => $Cf->internal) if $Cf->internal ne ":";
++        # $e->add(iusRestrictedMail => $Cf->internal) if $Cf->internal ne ":";
+ 
+-	$e->exists("sn") or $e->add(sn => $sn);
+-	$e->exists("cn") or $e->add(cn => $cn);
++        $e->exists("sn") or $e->add( sn => $sn );
++        $e->exists("cn") or $e->add( cn => $cn );
+ 
++        $r = $e->update($ldap);
++        die $r->error if $r->code;
+ 
+-	$r = $e->update($ldap);
+-	die $r->error if $r->code;
+-
+-	verbose("ok");
+-	verbose(" Password: $pw") if not $Cf->password or $Cf->password eq "{pwgen}";
++        verbose('ok');
++        verbose(" Password: $pw")
++          if not $Cf->password
++              or $Cf->password eq "{pwgen}";
+     }
+ 
+-    if($Cf->mbox) {
+-	verbose("\n\t$mbox...");
++    if ( $Cf->mbox ) {
+ 
+-	if ($imap->list($mbox)) { verbose("exists") }
+-	else {
+-	    $imap->create($mbox) and verbose("ok") or die $@;
+-	    $imap->setacl($mbox, $Cf->imap_admin => "lrswipcda") or die $@;
+-	    $imap->setquota($mbox, STORAGE => 1024 * $Cf->imap_quota) or die $@;
+-	}
++        verbose("\n\t$mbox...");
++
++        if ( -d $mbox ) {
++
++            verbose('exists')
++
++        } elsif ( ( $imap->login( $user, $pw ) or die $@ )
++            and $imap->capability->{acl} )
++        {
++
++            # wenn wir acl verwenden,
++            #  * dann triggert 'list' acl file (und damit maildir) erzeugung
++            #    bei dovecot
++            #  * müssen wir dem master nutzer ausdrücklich rechte gewähren
++            #  (sofern wir das nicht eleganter über globale acl regeln können)
++            #    (lra: sicht-, les- und administrierbar)
++            my $f = $imap->list( '', '*' ) or die $@;
++
++            #$imap->setacl( $f->[0]->[2], $Cf->imap_admin, 'lra' ) or die $@;
++            verbose('ok');
++
++        } else {
++
++            verbose('will be created automatically on first email delivery');
++
++        }
++
+     }
+ 
+-
+     verbose("\n");
+ }
+ 
+ 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 (@users) = @ARGV or die "Need username(s)\n";
+     my @dns;
+ 
+-    my $r = $ldap->search(base => $ubase, 
+-	filter => "(|" . join("", map { "(uid=$_)" } @ARGV) . ")");
++    my $r = $ldap->search(
++        base   => $ubase,
++        filter => "(|" . join( "", map { "(uid=$_)" } @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 $user = $e->get_value("uid");
+-	my $dn = $e->dn;
+-	my $mbox = "user/$user";
++        my $user = $e->get_value("uid");
++        my $dn   = $e->dn;
+ 
+-	my $modified = 0;
+-	verbose "$user:";
++        my $modified = 0;
++        verbose "$user:";
+ 
+-	verbose "\n\t$dn...";
++        verbose "\n\t$dn...";
+ 
+-	# Fix: iusMailOptions wurde erst später eingeführt, bei Bedarf also hinzufügen
+-	#if (!grep /^iusMailOptions$/, @{$e->get("objectClass")}) {
+-	    #$e->add(objectClass => "iusMailOptions");
+-	#}
++        # Fix: iusMailOptions wurde erst später eingeführt, bei Bedarf also hinzufügen
++        #if (!grep /^iusMailOptions$/, @{$e->get("objectClass")}) {
++        #$e->add(objectClass => "iusMailOptions");
++        #}
+ 
+-	if (my $cn = $Cf->fullname) {
+-	    # Aus dem Fullnamen leiten wir cn und sn ab.
+-	    my $sn = (reverse split " ", $cn)[0];
++        if ( my $cn = $Cf->fullname ) {
+ 
+-	    if ($cn =~ s/^\+//) {
+-		$e->replace(
+-		    cn => [uniq $e->get("cn"), $cn], 
+-		    sn => [uniq $e->get("sn"), $sn]);
+-	    } elsif ($cn =~ s/^-//) {
+-		$e->delete(cn => [$cn], sn => [$sn]);
+-	    } else { $e->replace(cn => $cn, sn => $sn); }
+-	    $modified++;
+-	}
++            # Aus dem Fullnamen leiten wir cn und sn ab.
++            my $sn = ( reverse split " ", $cn )[0];
+ 
+-	if (defined $Cf->other) {
+-	    my @o = split /,/, $Cf->other;
+-	    grep { /^[+-]/ } @o or $e->delete(AT_ADDRESS);
++            if ( $cn =~ s/^\+// ) {
++                $e->replace(
++                    cn => [ uniq $e->get("cn"), $cn ],
++                    sn => [ uniq $e->get("sn"), $sn ]
++                );
++            } elsif ( $cn =~ s/^-// ) {
++                $e->delete( cn => [$cn], sn => [$sn] );
++            } else {
++                $e->replace( cn => $cn, sn => $sn );
++            }
++            $modified++;
++        }
+ 
+-	    foreach my $a (split /,/, $Cf->other) {
+-		if ($a =~ s/^-//) { 
+-		    $e->delete((AT_ADDRESS) => [$a]) 
+-		} else {
+-		    $a =~ s/^\+//;
++        if ( defined $Cf->other ) {
++            my @o = split /,/, $Cf->other;
++            grep { /^[+-]/ } @o or $e->delete(AT_ADDRESS);
+ 
+-		    # Darf noch nicht woanders sein
+-		    $r = $ldap->search(base => $ubase, filter => "(mail=$a)");
+-		    die $r->error if $r->code;
+-		    die "$a ist schon vergeben\n" if $r->count;
++            foreach my $a ( split /,/, $Cf->other ) {
++                if ( $a =~ s/^-// ) {
++                    $e->delete( (AT_ADDRESS) => [$a] );
++                } else {
++                    $a =~ s/^\+//;
+ 
+-		    $e->add((AT_ADDRESS) => [$a]) 
+-		}
+-	    }
+-	    $modified++;
+-	}
++                    # Darf noch nicht woanders sein
++                    $r = $ldap->search( base => $ubase, filter => "(mail=$a)" );
++                    die $r->error if $r->code;
++                    die "$a ist schon vergeben\n" if $r->count;
+ 
+-	if (defined $Cf->group) {
+-	    my @g = split /,/, $Cf->group;
+-	    grep { /^[+-]/ } @g or $e->delete(AT_GROUP)
+-		if $e->get_value(AT_GROUP);
++                    $e->add( (AT_ADDRESS) => [$a] );
++                }
++            }
++            $modified++;
++        }
+ 
+-	    foreach my $g (@g) {
+-		if ($g =~ s/^-//) {
+-		    $e->delete((AT_GROUP) => [$g])
+-		} else {
+-		    $g =~ s/^\+//;
+-		    $e->add((AT_GROUP) => [$g])
+-		}
+-	    }
+-	    $modified++;
+-	}
++        if ( defined $Cf->group ) {
++            my @g = split /,/, $Cf->group;
++            grep { /^[+-]/ } @g
++              or $e->delete(AT_GROUP)
++              if $e->get_value(AT_GROUP);
+ 
+-	if (defined $Cf->forward) {
+-	    my @f = split /,/, $Cf->forward;
+-	    grep { /^[+-]/ } @f or $e->delete(AT_FORWARDINGADDRESS)
+-		if $e->get_value(AT_FORWARDINGADDRESS);
++            foreach my $g (@g) {
++                if ( $g =~ s/^-// ) {
++                    $e->delete( (AT_GROUP) => [$g] );
++                } else {
++                    $g =~ s/^\+//;
++                    $e->add( (AT_GROUP) => [$g] );
++                }
++            }
++            $modified++;
++        }
+ 
+-	    foreach my $f (@f) {
+-		if ($f =~ s/^-//) {
+-		    $e->delete((AT_FORWARDINGADDRESS) => [$f]);
+-		} else {
+-		    $f =~ s/^\+//;
+-		    $e->add((AT_FORWARDINGADDRESS) => [$f]);
+-		}
+-	    }
+-	    $modified++;
+-	}
++        if ( defined $Cf->forward ) {
++            my @f = split /,/, $Cf->forward;
++            grep { /^[+-]/ } @f
++              or $e->delete(AT_FORWARDINGADDRESS)
++              if $e->get_value(AT_FORWARDINGADDRESS);
+ 
+-	if (my $a = $Cf->primary) {
+-	    $r = $ldap->search(base => $ubase, 
+-		# filter => "(|(mailPrimaryAddress=$a)(mail=$a))");
+-		filter => "(mail=$a)");
+-	    die $r->error if $r->code;
+-	    die "$a ist schon vergeben\n" if $r->count;
+-    
+-	    $e->replace((AT_PRIMARYADDRESS) => $Cf->primary);
+-	    $modified++;
+-	}
++            foreach my $f (@f) {
++                if ( $f =~ s/^-// ) {
++                    $e->delete( (AT_FORWARDINGADDRESS) => [$f] );
++                } else {
++                    $f =~ s/^\+//;
++                    $e->add( (AT_FORWARDINGADDRESS) => [$f] );
++                }
++            }
++            $modified++;
++        }
+ 
+-	if (my $pw = _mkpw($Cf->password)) {
+-	    $e->replace(userPassword => $pw);
+-	    $modified++;
+-	}
++        if ( defined $Cf->quota ) {
++            $e->replace( (AT_QUOTA) => $Cf->quota );
++            $modified++;
++        }
+ 
+-	#if ($Cf->internal ne ":") {
+-	    #$e->replace(iusRestrictedMail => $Cf->internal ? "TRUE" : "FALSE");
+-	    #$modified++;
+-	#}
++        if ( defined $Cf->aclgroups ) {
+ 
+-	$e->dump if $Cf->debug;
++            my $ag = $Cf->aclgroups;
++            my $lag = $e->get_value(AT_ACLGROUPS); 
++            # groups should be supplied with leading '$' for consistency with
++            # dovecots imap acl, but should not be saved in ldap with it!
++            $ag =~ s/(^|,[+-]?)\K\$//g;
+ 
+-	if ($modified) {
+-	    $r = $e->update($ldap);
+-	    die $r->error.$r->code if $r->code;
+-	}
++            if ( $ag =~ /(^|,\s*)[+-]/ ) {
++                my %x;
++                @x{ split /,/, $lag } = ();
++                for ( split /,/, $ag ) {
++                    if (s/^-//) {
++                        delete $x{$_};
++                    } else {
++                        s/^\+//;
++                        $x{$_} = undef;
++                    }
++                }
+ 
+-	# FIXME: Wenn keine Mailbox existiert, gibt es hier ein Problem
+-	if (defined $Cf->imap_quota) {
+-	    $imap->setquota($mbox, STORAGE => $Cf->imap_quota * 1024)
+-	    or die $@;
+-	}
++                $ag = join ',', sort keys %x;
+ 
+-	verbose "ok\n";
++            }
+ 
+-	print "\n";
++            if ($ag) {
++                $e->replace( (AT_ACLGROUPS) => $ag );
++            } else {
++                $e->delete( AT_ACLGROUPS ) if $lag;
++            }
++            $modified++;
++        }
++
++        if ( my $a = $Cf->primary ) {
++            $r = $ldap->search(
++                base => $ubase,
++
++                # filter => "(|(mailPrimaryAddress=$a)(mail=$a))");
++                filter => "(mail=$a)"
++            );
++            die $r->error if $r->code;
++            die "$a ist schon vergeben\n" if $r->count;
++
++            $e->replace( (AT_PRIMARYADDRESS) => $Cf->primary );
++            $modified++;
++        }
++
++        if ( my $pw = _mkpw( $Cf->password ) ) {
++            $e->replace( userPassword => $pw );
++            $modified++;
++        }
++
++        #if ($Cf->internal ne ":") {
++        #$e->replace(iusRestrictedMail => $Cf->internal ? "TRUE" : "FALSE");
++        #$modified++;
++        #}
++
++        $e->dump if $Cf->debug;
++
++        if ($modified) {
++            $r = $e->update($ldap);
++            die $r->error . $r->code if $r->code;
++        }
++
++        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 "User: ";
+-	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 "User: ";
++        chomp( $_ = <> );
++        @ARGV = ($_);
+     }
+ 
++    foreach (@ARGV) {
++        my $user = $_;
++        my $dn   = "uid=$user,$ubase";
+ 
+-    foreach (@ARGV) {
+-	my $user = $_;
+-	my $dn = "uid=$user,$ubase";
+-	my $mbox = "user/$user";
++        verbose("$user:\n");
+ 
+-	verbose("$user:\n");
++        # Nachsehen, ob es noch aliase gibt, in denen dieser Nutzer steht:
++        my $r = $ldap->search(
++            base   => $abase,
++            filter => "(" . AT_FORWARDINGADDRESS . "=$_)",
++            attrs  => [ "mail", AT_FORWARDINGADDRESS ]
++        );
++        while ( my $e = $r->shift_entry ) {
++            verbose("\tdeleting $user from alias "
++                  . $e->get_value("mail")
++                  . "..." );
++            $e->delete( (AT_FORWARDINGADDRESS) => [$user] );
+ 
+-	# Nachsehen, ob es noch aliase gibt, in denen dieser Nutzer steht:
+-	my $r = $ldap->search(base => $abase,
+-	    filter => "(".AT_FORWARDINGADDRESS."=$_)",
+-	    attrs => ["mail", AT_FORWARDINGADDRESS]);
+-	while (my $e = $r->shift_entry) {
+-	    verbose("\tdeleting $user from alias ".$e->get_value("mail")."...");
+-	    $e->delete((AT_FORWARDINGADDRESS) => [$user]);
++            my $r = $e->update($ldap);
++            if   ( $r->code == 0 ) { verbose("ok\n") }
++            else                   { die $r->error }
++        }
+ 
+-	    my $r = $e->update($ldap);
+-	    if ($r->code == 0) { verbose("ok\n") } 
+-	    else { die $r->error }
+-	}
++        verbose("\tdeleting $dn...");
++        $r = $ldap->delete($dn);
+ 
+-	verbose("\tdeleting $dn...");
+-	$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");
+-	
+-	if ($Cf->mbox) {
+-	    verbose("\tdeleting mbox $mbox...");
+-	    $imap->delete($mbox) and verbose("ok")
+-	    or verbose($imap->error);
+-	}
++        if ( $Cf->mbox ) {
++            my $m = _mbox($user);
++            if ( not( defined $m and $m ) ) {
++                verbose("can't determine mbox location - not deleting it");
++            } else {
++                verbose("\tdeleting $m...");
++                verbose( ( remove_tree $m) ? 'ok' : " Can't remove '$m': $!" );
++            }
++        }
+ 
+-	verbose("\n");
++        print
++          "Don't forget to remove acl entries for this user if any exist!\n";
++        verbose("\n");
+ 
+     }
+ }