summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 2846dab)
raw | patch | inline | side by side (parent: 2846dab)
author | hickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Fri, 13 Jul 2007 12:44:09 +0000 (12:44 +0000) | ||
committer | hickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Fri, 13 Jul 2007 12:44:09 +0000 (12:44 +0000) |
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@6860 594d385d-05f5-0310-b6e9-bd551577e9d8
contrib/scripts/sieve_vacation/IMAP/Sieve.pm | [new file with mode: 0644] | patch | blob |
contrib/scripts/sieve_vacation/update-vacation.pl | [new file with mode: 0755] | patch | blob |
diff --git a/contrib/scripts/sieve_vacation/IMAP/Sieve.pm b/contrib/scripts/sieve_vacation/IMAP/Sieve.pm
--- /dev/null
@@ -0,0 +1,401 @@
+# $Id: Sieve.pm,v 0.4.9b 2001/06/15 19:25:00 alain Exp $
+
+package IMAP::Sieve;
+
+use strict;
+use Carp;
+use IO::Select;
+use IO::Socket;
+use IO::Socket::INET;
+#use Text::ParseWords qw(parse_line);
+use Cwd;
+
+use vars qw($VERSION);
+
+$VERSION = '0.4.9b';
+
+sub new {
+ my $class = shift;
+ my $self = {};
+ bless $self, $class;
+ if ((scalar(@_) % 2) != 0) {
+ croak "$class called with incorrect number of arguments";
+ }
+ while (@_) {
+ my $key = shift(@_);
+ my $value = shift(@_);
+ $self->{$key} = $value;
+ }
+ $self->{'CLASS'} = $class;
+ $self->_initialize;
+ return $self;
+}
+
+sub _initialize {
+ my $self = shift;
+ my ($len,$userpass,$encode);
+ if (!defined($self->{'Server'})) {
+ croak "$self->{'CLASS'} not initialized properly : Server parameter missing";
+ }
+ if (!defined($self->{'Port'})) {
+ $self->{'Port'} = 2000; # default sieve port;
+ }
+ if (!defined($self->{'Login'})) {
+ croak "$self->{'CLASS'} not initialized properly : Login parameter missing";
+ }
+ if (!defined($self->{'Password'})) {
+ croak "$self->{'CLASS'} not initialized properly : Password parameter missing";
+ }
+ if (!defined($self->{'Proxy'})) {
+ $self->{'Proxy'} = ''; # Proxy;
+ }
+ if (defined($self->{'SSL'})) {
+ my $cwd= cwd;
+ my %ssl_defaults = (
+ 'SSL_use_cert' => 0,
+ 'SSL_verify_mode' => 0x00,
+ 'SSL_key_file' => $cwd."/certs/client-key.pem",
+ 'SSL_cert_file' => $cwd."/certs/client-cert.pem",
+ 'SSL_ca_path' => $cwd."/certs",
+ 'SSL_ca_file' => $cwd."/certs/ca-cert.pem",
+ );
+ my @ssl_options;
+ my $ssl_key;
+ my $key;
+ foreach $ssl_key (keys(%ssl_defaults)) {
+ if (!defined($self->{$ssl_key})) {
+ $self->{$ssl_key} = $ssl_defaults{$ssl_key};
+ }
+ }
+ foreach $ssl_key (keys(%{$self})) {
+ if ($ssl_key =~ /^SSL_/) {
+ push @ssl_options, $ssl_key,$self->{$ssl_key};
+ }
+ }
+ my $SSL_try="use IO::Socket::SSL";
+ eval $SSL_try;
+ if (!eval {$self->{'Socket'} =
+ IO::Socket::SSL->new(PeerAddr => $self->{'Server'},
+ PeerPort => $self->{'Port'},
+ Proto => 'tcp',
+ Reuse => 1,
+ Timeout => 5,
+ @ssl_options);}) {
+ $self->_error("initialize", "couldn't establish a sieve SSL connection to",$self->{'Server'}, "[$!]","path=$cwd");
+ delete $self->{'Socket'};
+ return;
+ }
+ }
+ else {
+
+ if (!eval {$self->{'Socket'} = IO::Socket::INET->new(PeerAddr => $self->{'Server'},
+ PeerPort => $self->{'Port'},
+ Proto => 'tcp',
+ Reuse => 1); })
+ {
+ $self->_error("initialize", "could'nt establish a Sieve connection to",$self->{'Server'});
+ return;
+ }
+ } # if SSL
+
+ my $fh = $self->{'Socket'};
+ $_ = $self->_read; #get banner
+ my $try=$_;
+ if (!/timsieved/i) {
+ $self->close;
+ $self->_error("initialize","bad response from",$self->{'Server'},$try);
+ return;
+ }
+ chomp;
+ if (/\r$/) {
+ chop;
+ }
+ if (/IMPLEMENTATION/) {
+ $self->{'Implementation'}=$1 if /^"IMPLEMENTATION" +"(.*)"/;
+ #version 2 of cyrus imap/timsieved
+ # get capability
+ # get OK as well
+ $_=$self->_read;
+ while (!/^OK/) {
+ $self->{'Capability'}=$1 if /^"SASL" +"(.*)"/;
+ $self->{'Sieve'}=$1 if /^"SIEVE" +"(.*)"/;
+ $_ = $self->_read;
+## $_=$self->_read;
+ }
+ }
+ else {
+ $self->{'Capability'}=$_;
+ }
+ $userpass = "$self->{'Proxy'}\x00".$self->{'Login'}."\x00".$self->{'Password'};
+ $encode=encode_base64($userpass);
+ $len=length($encode);
+ print $fh "AUTHENTICATE \"PLAIN\" {$len+}\r\n";
+
+ print $fh "$encode\r\n";
+
+ $_ = $self->_read;
+ $try=$_;
+ if ($try=~/NO/) {
+ $self->close;
+ $self->_error("Login incorrect while connecting to $self->{'Server'}", $try);
+ return;
+ } elsif (/OK/) {
+ $self->{'Error'}= "No Errors";
+ return;
+ } else {
+ #croak "$self->{'CLASS'}: Unknown error -- $_";
+ $self->_error("Unknown error",$try);
+ return;
+ }
+ $self->{'Error'}="No Errors";
+ return;
+}
+sub encode_base64 ($;$)
+{
+ my $res = "";
+ my $eol = $_[1];
+ $eol = "\n" unless defined $eol;
+ pos($_[0]) = 0; # ensure start at the beginning
+ while ($_[0] =~ /(.{1,45})/gs) {
+ $res .= substr(pack('u', $1), 1);
+ chop($res);
+ }
+ $res =~ tr|` -_|AA-Za-z0-9+/|; # `# help emacs
+ # fix padding at the end
+ my $padding = (3 - length($_[0]) % 3) % 3;
+ $res =~ s/.{$padding}$/'=' x $padding/e if $padding;
+ # break encoded string into lines of no more than 76 characters each
+ if (length $eol) {
+ $res =~ s/(.{1,76})/$1$eol/g;
+ }
+ $res;
+}
+
+
+sub _error {
+ my $self = shift;
+ my $func = shift;
+ my @error = @_;
+
+ $self->{'Error'} = join(" ",$self->{'CLASS'}, "[", $func, "]:", @error);
+}
+
+sub _read {
+ my $self = shift;
+ my $buffer ="";
+ my $char = "";
+ my $bytes= 1;
+ while ($bytes == 1) {
+ $bytes = sysread $self->{'Socket'},$char,1;
+ if ($bytes == 0) {
+ if (length ($buffer) != 0) {
+ return $buffer;
+ }
+ else {
+ return;
+ }
+ }
+ else {
+ if (($char eq "\n") or ($char eq "\r")) {
+ if (length($buffer) ==0) {
+ # remove any cr or nl leftover
+ }
+ else {
+ return $buffer;
+ }
+ }
+ else {
+ $buffer.=$char;
+ }
+ }
+ }
+}
+
+
+sub close {
+ my $self = shift;
+ if (!defined($self->{'Socket'})) {
+ return 0;
+ }
+ my $fh =$self->{'Socket'};
+ print $fh "LOGOUT\r\n";
+ close($self->{'Socket'});
+ delete $self->{'Socket'};
+}
+
+sub putscript {
+ my $self = shift;
+ my $len;
+
+ if (scalar(@_) != 2) {
+ $self->_error("putscript", "incorrect number of arguments");
+ return 1;
+ }
+
+ my $scriptname = shift;
+ my $script = shift;
+
+ if (!defined($self->{'Socket'})) {
+ $self->_error("putscript", "no connection open to", $self->{'Server'});
+ return 1;
+ }
+ $len=length($script);
+ my $fh = $self->{'Socket'};
+ print $fh "PUTSCRIPT \"$scriptname\" {$len+}\r\n";
+ print $fh "$script\r\n";
+ $_ = $self->_read;
+ if (/^OK/) {
+ $self->{'Error'} = 'No Errors';
+ return 0;
+ } else {
+ $self->_error("putscript", "couldn't save script", $scriptname, ":", $_);
+ return 1;
+ }
+}
+
+sub deletescript {
+ my $self = shift;
+
+ if (scalar(@_) != 1) {
+ $self->_error("deletescript", "incorrect number of arguments");
+ return 1;
+ }
+ my $script = shift;
+ if (!defined($self->{'Socket'})) {
+ $self->_error("deletescript", "no connection open to", $self->{'Server'});
+ return 1;
+ }
+ my $fh = $self->{'Socket'};
+ print $fh "DELETESCRIPT \"$script\"\r\n";
+ $_ = $self->_read;
+ if (/^OK/) {
+ $self->{'Error'} = 'No Errors';
+ return 0;
+ } else {
+ $self->_error("deletescript", "couldn't delete", $script, ":", $_);
+ return 1;
+ }
+}
+sub getscript { # returns a string
+ my $self = shift;
+ my $allscript;
+
+ if (scalar(@_) != 1) {
+ $self->_error("getscript", "incorrect number of arguments");
+ return 1;
+ }
+ my $script = shift;
+ if (!defined($self->{'Socket'})) {
+ $self->_error("getscript", "no connection open to", $self->{'Server'});
+ return 1;
+ }
+ my $fh = $self->{'Socket'};
+ print $fh "GETSCRIPT \"$script\"\r\n";
+ $_ = $self->_read;
+ if (/^{.*}/) { $_ = $self->_read; } # remove file size line
+
+ # should probably use the file size to calculate how much to read in
+ while ((!/^OK/) && (!/^NO/)) {
+ $_.="\n" if $_ !~/\n.*$/; # replace newline that _read removes
+ $allscript.=$_;
+ $_ = $self->_read;
+ }
+ if (/^OK/) {
+ return $allscript;
+ } else {
+ $self->_error("getscript", "couldn't get script", $script, ":", $_);
+ return;
+ }
+}
+
+sub setactive {
+ my $self = shift;
+
+ if (scalar(@_) != 1) {
+ $self->_error("setactive", "incorrect number of arguments");
+ return 1;
+ }
+ my $script = shift;
+ if (!defined($self->{'Socket'})) {
+ $self->_error("setactive", "no connection open to", $self->{'Server'});
+ return 1;
+ }
+ my $fh = $self->{'Socket'};
+ print $fh "SETACTIVE \"$script\"\r\n";
+ $_ = $self->_read;
+ if (/^OK/) {
+ $self->{'Error'} = "No Errors";
+ return 0;
+ } else {
+ $self->_error("setactive", "couldn't set as active", $script, ":", $_);
+ return 1;
+ }
+}
+
+
+sub noop {
+ my $self = shift;
+ my ($id, $acl);
+
+ if (!defined($self->{'Socket'})) {
+ $self->_error("noop", "no connection open to", $self->{'Server'});
+ return 1;
+ }
+ my $fh = $self->{'Socket'};
+ print $fh "NOOP\r\n";
+ $_ = $self->_read;
+ if (!/^OK/) {
+ $self->_error("noop", "couldn't do noop"
+ );
+ return 1;
+ }
+ $self->{'Error'} = 'No Errors';
+ return 0;
+}
+
+
+sub listscripts {
+ my $self = shift;
+ my (@scripts);
+
+ if (!defined($self->{'Socket'})) {
+ $self->_error("listscripts", "no connection open to", $self->{'Server'});
+ return;
+ }
+
+ #send the command
+ $self->{'Socket'}->print ("LISTSCRIPTS\r\n");
+
+ # While we have more to read
+ while (defined ($_ = $self->_read)) {
+
+ # Exit the loop if we're at the end of the text
+ last if (m/^OK.*/);
+
+ # Select the stuff between the quotes (without the asterisk)
+ # m/^"([^"]+?)\*?"\r?$/;
+ # Select including the asterisk (to determine the default script)
+# m/^"([^"]+?\*?)"\r?$/;
+ $_=~s/"//g;
+ # Get the name of the script
+ push @scripts, $_;
+ }
+
+ if (/^OK/) {
+ return @scripts;
+ } else {
+
+
+
+ }
+ if (/^OK/) {
+ return @scripts;
+ } else {
+ $self->_error("list", "couldn't get list for", ":", $_);
+ return;
+ }
+}
+
+1;
+__END__
+
diff --git a/contrib/scripts/sieve_vacation/update-vacation.pl b/contrib/scripts/sieve_vacation/update-vacation.pl
--- /dev/null
@@ -0,0 +1,477 @@
+#!/usr/bin/perl -w -I.
+#
+# This code is part of GOsa (https://gosa.gonicus.de)
+# Copyright (C) 2007 Frank Moeller
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+use strict;
+use IMAP::Sieve;
+use XML::Simple;
+use Data::Dumper;
+use Net::LDAP;
+use utf8;
+use Getopt::Std;
+use vars qw/ %opt /;
+
+#
+# Definitions
+#
+my $gosa_config = "/etc/gosa/gosa.conf";
+my $opt_string = 'l:h';
+my $location = "";
+my $today = time ();
+# default mailMethod = kolab
+my $server_attribute = "kolabHomeServer";
+my $alternate_address_attribute = "alias";
+my $gosa_sieve_script_name = "gosa";
+my $simple_bind_dn = "";
+my $simple_bind_dn_pwd = "";
+my $gosa_sieve_script_status = "FALSE";
+my $sieve_vacation = "";
+my $gosa_sieve_spam_header = "Sort mails with higher spam level";
+
+#
+# Templates
+#
+my $gosa_sieve_header = "\#\#\#GOSA\nrequire\ \[\"fileinto\",\ \"reject\",\ \"vacation\"\]\;\n\n";
+my $vacation_header_template = "\# Begin vacation message";
+my $vacation_footer_template = "\# End vacation message";
+
+#
+# Usage
+#
+sub usage {
+ die "Usage:\nperl $0 [option]\n\n\tOptions:\n\t\t-l <\"location name\">\tuse special location\n\t\t-h\t\t\tthis help \n";
+}
+
+#
+# Config import
+#
+sub read_config {
+ my $input = shift || die "need config file: $!";
+ my $stream = "";
+ open ( FILE, "< $input" ) or die "Error opening file $input: $! \n";
+ {
+ local $/ = undef;
+ $stream = <FILE>;
+ }
+ close ( FILE );
+ return $stream;
+}
+
+#
+# XML parser
+#
+sub parseconfig {
+ my $c_location = shift;
+ my $xmldata = shift;
+ my $xml = new XML::Simple ();
+ my $c_data = $xml -> XMLin( $xmldata );
+ my $config = {};
+ my $server = $c_data->{main}->{location}->{$c_location}->{server};
+ my $config_base = $c_data->{main}->{location}->{$c_location}->{config};
+ my $ldap_admin = $c_data->{main}->{location}->{$c_location}->{referral}->{admin};
+ my $ldap_admin_pwd = $c_data->{main}->{location}->{$c_location}->{referral}->{password};
+ my $mailMethod = $c_data->{main}->{location}->{$c_location}->{mailMethod};
+ $config->{server} = $server;
+ $config->{config_base} = $config_base;
+ $config->{mailMethod} = $mailMethod;
+ $config->{ldap_admin} = $ldap_admin;
+ $config->{ldap_admin_pwd} = $ldap_admin_pwd;
+
+ return $config;
+}
+
+#
+# Get default location
+#
+sub get_default_location {
+ my $xmldata = shift;
+ my $xml = new XML::Simple ( RootName=>'conf' );
+ my $c_data = $xml -> XMLin( $xmldata );
+ my $default = $c_data->{main}->{default};
+
+ return $default;
+}
+
+#
+# LDAP error handling
+#
+sub ldap_error {
+ my ($from, $mesg) = @_;
+ print "Return code: ", $mesg->code;
+ print "\tMessage: ", $mesg->error_name;
+ print " :", $mesg->error_text;
+ print "MessageID: ", $mesg->mesg_id;
+ print "\tDN: ", $mesg->dn;
+}
+
+
+#
+# LDAP search
+#
+sub ldap_search {
+ my $url = shift;
+ my $searchString = shift;
+ my $scope = shift;
+ my $base = shift;
+ my $attrs = shift;
+ my $bind_dn = shift;
+ my $bind_dn_pwd = shift;
+
+ if ( $base eq "NULL" ) {
+ $base = "";
+ }
+ my $ldap = Net::LDAP->new( $url ) or die "$@";
+ if ( ( ! ( $bind_dn ) ) || ( ! ( $bind_dn_pwd ) ) ) {
+ $ldap->bind;
+ } else {
+ $ldap->bind ( $bind_dn, password => $bind_dn_pwd );
+ }
+
+ my $result = $ldap->search ( base => "$base",
+ scope => "$scope",
+ filter => "$searchString",
+ attrs => $attrs
+ );
+ if ( $result->code ) {
+ ldap_error ( "Searching", $result );
+ }
+
+ $ldap->unbind;
+
+ return $result;
+}
+
+#
+# Retrieve LDAP base
+#
+sub get_ldap_base {
+ my $url = shift;
+ my $config_base = shift;
+ my $bind_dn = shift;
+ my $bind_dn_pwd = shift;
+ my $filter = "(objectClass=*)";
+ my $init_base = "NULL";
+ my $scope = "base";
+ my $attributes = [ 'namingcontexts' ];
+ my $entry = {};
+ my $base = "";
+
+ $config_base =~ s/\,\ +/\,/g;
+ print $url."\n";
+ print $config_base."\n";
+ my $result = ldap_search ( $url, $filter, $scope, $init_base, $attributes, $bind_dn, $bind_dn_pwd );
+ my @entries = $result->entries;
+ my $noe = @entries;
+ print $noe."\n";
+ foreach $entry ( @entries ) {
+ my $tmp = $entry->get_value ( 'namingcontexts' );
+ print $tmp."\n";
+ $tmp =~ s/\,\ +/\,/g;
+ if ( $config_base =~ m/$tmp/ ) {
+ $base = $entry->get_value ( 'namingcontexts' );
+ }
+ }
+
+ return $base;
+}
+
+#
+# SIEVE functions
+#
+sub opensieve {
+ my $admin = shift;
+ my $pass = shift;
+ my $user = shift;
+ my $server = shift;
+ my $port = shift;
+
+ print ( "##### Proxy => $user, Server => $server, Login => $admin, Password => $pass, Port => $port ####\n" );
+
+ my $sieve = IMAP::Sieve->new ( 'Proxy' => $user, 'Server' => $server, 'Login' => $admin, 'Password' => $pass, 'Port' => $port );
+ return $sieve;
+}
+
+sub closesieve {
+ my $sieve = shift;
+
+ if ($sieve) {$sieve->close};
+}
+
+sub listscripts {
+ my $sieve = shift;
+
+ my @scripts = $sieve->listscripts;
+ my $script_list = join("\n",@scripts)."\n";
+ return $script_list;
+}
+
+sub getscript {
+ my $sieve = shift;
+ my $script = shift;
+ my $scriptfile;
+ chomp $script;
+ #print "$sieve\n";
+ #print "$script\n";
+
+ $scriptfile = $sieve->getscript($script);
+ return $scriptfile;
+}
+
+sub putscript {
+ my $sieve = shift;
+ my $scriptname = shift;
+ my $script = shift;
+ print "$sieve\n";
+ print "$scriptname\n";
+ print "$script\n";
+
+ my $res=$sieve->putscript($scriptname,$script);
+ if ($res) {print $sieve->{'Error'}}
+ return;
+}
+
+sub setactive {
+ my $sieve = shift;
+ my $script = shift;
+
+ my $res=$sieve->setactive($script);
+ if ($res) { print $sieve->{'Error'};}
+ return;
+}
+
+#
+# main ()
+#
+# read options
+getopts( "$opt_string", \%opt );
+
+# read GOsa config
+my $input_stream = read_config ( $gosa_config );
+
+# get location
+if ( $opt{l} ) {
+ $location = $opt{l};
+} elsif ( $opt{h} ) {
+ usage ();
+ exit (0);
+} else {
+ $location = get_default_location ( $input_stream );
+}
+print "$location\n";
+
+# parse config
+my $config = parseconfig ( $location, $input_stream );
+my $ldap_url = $config->{server};
+my $gosa_config_base = $config->{config_base};
+my $bind_dn = $config->{ldap_admin};
+my $bind_dn_pwd = $config->{ldap_admin_pwd};
+my $mailMethod = $config->{mailMethod};
+utf8::encode($ldap_url);
+utf8::encode($gosa_config_base);
+utf8::encode($mailMethod);
+
+if ( $mailMethod =~ m/cyrus/i ) {
+ my $server_attribute = "gosaMailServer";
+ my $alternate_address_attribute = "gosaMailAlternateAddress";
+}
+
+# determine LDAP base
+my $ldap_base = get_ldap_base ( $ldap_url, $gosa_config_base, $simple_bind_dn, $simple_bind_dn_pwd );
+
+# retrieve user informations with activated vacation feature
+my $filter = "(&(objectClass=gosaMailAccount)(gosaMailDeliveryMode=*V*)(!(gosaMailDeliveryMode=*C*)))";
+my $list_of_attributes = [ 'uid', 'mail', $alternate_address_attribute, 'gosaVacationMessage', 'gosaVacationStart', 'gosaVacationStop', $server_attribute ];
+my $search_scope = "sub";
+my $result = ldap_search ( $ldap_url, $filter, $search_scope, $ldap_base, $list_of_attributes, $simple_bind_dn, $simple_bind_dn_pwd );
+
+my @entries = $result->entries;
+my $entry = {};
+foreach $entry ( @entries ) {
+ my $uid_v = $entry->get_value ( 'uid' );
+ my $mail_v = $entry->get_value ( 'mail' );
+ my @mailalternate = $entry->get_value ( $alternate_address_attribute );
+ my $vacation = $entry->get_value ( 'gosaVacationMessage' );
+ my $start_v = $entry->get_value ( 'gosaVacationStart' );
+ my $stop_v = $entry->get_value ( 'gosaVacationStop' );
+ my $server_v = $entry->get_value ( $server_attribute );
+ if ( ! ( $uid_v ) ) {
+ $uid_v = "";
+ }
+ if ( ! ( $mail_v ) ) {
+ $mail_v = "";
+ }
+ my @mailAddress = ($mail_v);
+ my $alias = "";
+ foreach $alias ( @mailalternate ) {
+ push @mailAddress, $alias;
+ }
+ my $addresses = "";
+ foreach $alias ( @mailAddress ) {
+ $addresses .= "\"" . $alias . "\", ";
+ }
+ $addresses =~ s/\ *$//;
+ $addresses =~ s/\,$//;
+ if ( ! ( $vacation ) ) {
+ $vacation = "";
+ }
+ if ( ! ( $start_v ) ) {
+ $start_v = 0;
+ }
+ if ( ! ( $stop_v ) ) {
+ $stop_v = 0;
+ }
+ if ( ! ( $server_v ) ) {
+ $server_v = "";
+ next;
+ }
+ print $uid_v . " | " .
+ $addresses . " | " .
+ "\n";
+
+ my ($sieve_user, $tmp) = split ( /\@/, $mail_v );
+
+ if ( ( $today >= $start_v ) && ( $today < $stop_v ) ) {
+ print "activating vacation for user $uid_v\n";
+
+ my $srv_filter = "(&(goImapName=$server_v)(objectClass=goImapServer))";
+ my $srv_list_of_attributes = [ 'goImapSieveServer', 'goImapSievePort', 'goImapAdmin', 'goImapPassword' ];
+ my $srv_result = ldap_search ( $ldap_url, $srv_filter, $search_scope, $ldap_base, $srv_list_of_attributes, $bind_dn, $bind_dn_pwd );
+ my @srv_entries = $srv_result->entries;
+ my $srv_entry = {};
+ my $noe = @srv_entries;
+ if ( $noe == 0 ) {
+ printf STDERR "Error: no $server_attribute defined! Aboarting...";
+ } elsif ( $noe > 1 ) {
+ printf STDERR "Error: multiple $server_attribute defined! Aboarting...";
+ } else {
+ my $goImapSieveServer = $srv_entries[0]->get_value ( 'goImapSieveServer' );
+ my $goImapSievePort = $srv_entries[0]->get_value ( 'goImapSievePort' );
+ my $goImapAdmin = $srv_entries[0]->get_value ( 'goImapAdmin' );
+ my $goImapPassword = $srv_entries[0]->get_value ( 'goImapPassword' );
+ if ( ( $goImapSieveServer ) && ( $goImapSievePort ) && ( $goImapAdmin ) && ( $goImapPassword ) ) {
+ my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $sieve_user, $goImapSieveServer, $goImapSievePort);
+ my @sieve_scripts = listscripts ( $sieve );
+ my $script_name = "";
+ if ( @sieve_scripts ) {
+ foreach $script_name ( @sieve_scripts ) {
+ if ( $script_name =~ m/$gosa_sieve_script_name/ ) {
+ $gosa_sieve_script_status = "TRUE";
+ }
+ }
+ if ( $gosa_sieve_script_status eq "TRUE" ) {
+ print "retrieving and modifying gosa sieve script\n";
+ # requirements
+ my $sieve_script = getscript( $sieve, $gosa_sieve_script_name );
+ #print "$sieve_script\n";
+ if ( ! ( $sieve_script ) ) {
+ print "No Sieve Script! Creating New One!\n";
+ $sieve_script = $gosa_sieve_header;
+ }
+ if ( $sieve_script =~ m/require.*\[.*["|'] *vacation *["|'].*\]/ ) {
+ print "require vacation ok\n";
+ } else {
+ print "require vacation not ok\n";
+ print "modifying require statement\n";
+ $sieve_script =~ s/require(.*\[.*)\]/require$1\, "vacation"\]/;
+ }
+ if ( ! ( $sieve_script =~ m/$vacation_header_template/ ) ) {
+ print "no match header template\n";
+ $sieve_vacation = $vacation_header_template .
+ "\n" .
+ "vacation :addresses [$addresses]\n" .
+ "\"" .
+ $vacation .
+ "\n\"\;" .
+ "\n" .
+ $vacation_footer_template .
+ "\n\n";
+ }
+ #print ( "$sieve_vacation\n" );
+ #print ( "$sieve_script\n" );
+ # including vacation message
+ if ( $sieve_script =~ m/$gosa_sieve_spam_header/ ) {
+ print "MATCH\n";
+ $sieve_script =~ s/($gosa_sieve_spam_header[^{}]*{[^{}]*})/$1\n\n$sieve_vacation/;
+ } else {
+ $sieve_script =~ s/require(.*\[.*\])/require$1\n\n$sieve_vacation/;
+ }
+ print ( "START SIEVE $sieve_script\nSTOP SIEVE" );
+ # uploading new sieve script
+ putscript( $sieve, $gosa_sieve_script_name, $sieve_script );
+ # activating new sieve script
+ setactive( $sieve, $gosa_sieve_script_name );
+ } else {
+ print "no gosa script available, creating new one";
+ my $sieve_script = $gosa_sieve_header . "\n\n" . $sieve_vacation;
+ # uploading new sieve script
+ putscript( $sieve, $gosa_sieve_script_name, $sieve_script );
+ # activating new sieve script
+ setactive( $sieve, $gosa_sieve_script_name );
+ }
+ }
+ }
+ }
+ } elsif ( $today >= $stop_v ) {
+ print "deactivating vacation for user $uid_v\n";
+
+ my $srv_filter = "(&(goImapName=$server_v)(objectClass=goImapServer))";
+ my $srv_list_of_attributes = [ 'goImapSieveServer', 'goImapSievePort', 'goImapAdmin', 'goImapPassword' ];
+ my $srv_result = ldap_search ( $ldap_url, $srv_filter, $search_scope, $ldap_base, $srv_list_of_attributes, $bind_dn, $bind_dn_pwd );
+ my @srv_entries = $srv_result->entries;
+ my $srv_entry = {};
+ my $noe = @srv_entries;
+ if ( $noe == 0 ) {
+ printf STDERR "Error: no $server_attribute defined! Aboarting...";
+ } elsif ( $noe > 1 ) {
+ printf STDERR "Error: multiple $server_attribute defined! Aboarting...";
+ } else {
+ my $goImapSieveServer = $srv_entries[0]->get_value ( 'goImapSieveServer' );
+ my $goImapSievePort = $srv_entries[0]->get_value ( 'goImapSievePort' );
+ my $goImapAdmin = $srv_entries[0]->get_value ( 'goImapAdmin' );
+ my $goImapPassword = $srv_entries[0]->get_value ( 'goImapPassword' );
+ if ( ( $goImapSieveServer ) && ( $goImapSievePort ) && ( $goImapAdmin ) && ( $goImapPassword ) ) {
+ my $sieve = opensieve ( $goImapAdmin, $goImapPassword, $sieve_user, $goImapSieveServer, $goImapSievePort);
+ my @sieve_scripts = listscripts ( $sieve );
+ my $script_name = "";
+ if ( @sieve_scripts ) {
+ foreach $script_name ( @sieve_scripts ) {
+ if ( $script_name =~ m/$gosa_sieve_script_name/ ) {
+ $gosa_sieve_script_status = "TRUE";
+ }
+ }
+ if ( $gosa_sieve_script_status eq "TRUE" ) {
+ # removing vacation part
+ my $sieve_script = getscript( $sieve, $gosa_sieve_script_name );
+ if ( $sieve_script ) {
+ print "OLD SIEVE SCRIPT:\n$sieve_script\n\n";
+ #$sieve_script =~ s/$vacation_header_template[^#]Yp.*$vacation_footer_template//;
+ $sieve_script =~ s/$vacation_header_template[^#]*$vacation_footer_template//;
+ print "NEW SIEVE SCRIPT:\n$sieve_script\n\n";
+ # uploading new sieve script
+ putscript( $sieve, $gosa_sieve_script_name, $sieve_script );
+ # activating new sieve script
+ setactive( $sieve, $gosa_sieve_script_name );
+ }
+ }
+ }
+ }
+ }
+ } else {
+ print "no vacation process necessary\n";
+ }
+}