gunnar: server/perl-kolab/perl-kolab/lib/Kolab Conf.pm, NONE, 1.1 Cyrus.pm, NONE, 1.1 LDAP.pm, NONE, 1.1 Util.pm, NONE, 1.1
cvs at kolab.org
cvs at kolab.org
Tue Feb 16 06:33:44 CET 2010
- Previous message: gunnar: server/perl-kolab/perl-kolab/bin .cvsignore, NONE, 1.1 kolab_smtpdpolicy.in, NONE, 1.1 kolabdcachetool.in, NONE, 1.1 kolabpasswd.in, NONE, 1.1 kolabquotareport.in, NONE, 1.1 kolabquotawarn.in, NONE, 1.1
- Next message: gunnar: server/perl-kolab/perl-kolab/lib/Kolab/LDAP/Backend ad.pm, NONE, 1.1 fds.pm, NONE, 1.1 slurpd.pm, NONE, 1.1 syncrepl.pm, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: gunnar
Update of /kolabrepository/server/perl-kolab/perl-kolab/lib/Kolab
In directory doto:/tmp/cvs-serv3473/perl-kolab/lib/Kolab
Added Files:
Conf.pm Cyrus.pm LDAP.pm Util.pm
Log Message:
Move the perl-kolab sources into their own subdirectory.
--- NEW FILE: Conf.pm ---
package Kolab::Conf;
## COPYRIGHT
## ---------
##
## See AUTHORS file
##
##
## LICENSE
## -------
##
## 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, 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 can view the GNU General Public License, online, at the GNU
## Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
##
## $Revision: 1.1 $
use 5.008;
use strict;
use warnings;
use IO::File;
use File::Copy;
use File::Temp;
use File::stat;
use Kolab;
use Kolab::Util;
use Kolab::LDAP;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
'all' => [ qw(
&rebuildTemplates
&checkPermissions
) ]
);
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
);
my %templates = ();
my %ownership = ();
my %permissions = ();
my %confighaschanged = ();
my %commentchar = ();
sub fixup {
my $file = shift;
my $ownership = shift;
my $perm = shift;
(my $owner, my $group) = split(/:/, $ownership, 2);
my $uid = (getpwnam($owner))[2];
my $gid = (getgrnam($group))[2];
Kolab::log('T', sprintf("Changing permissions of %s to 0%o", $file, $perm ), KOLAB_DEBUG );
if( chmod($perm, $file) != 1 ) {
Kolab::log('T', "Unable to change permissions of `$file' to ".sprintf("0%o",$perm) . ": $!", KOLAB_ERROR);
exit(1);
}
Kolab::log('T', "Changing owner of $file to $owner:$group ($uid:$gid)", KOLAB_DEBUG );
if( chown($uid,$gid,$file) != 1 ) {
Kolab::log('T', "Unable to change ownership of `$file' to $uid:$gid: $!", KOLAB_ERROR);
exit(1);
}
}
sub printWarning {
my $stream = shift;
my $templateFile = shift;
my $cc = shift;
$templateFile = "" if (!defined $templateFile);
$cc = "#" if (!defined $cc);
# Different warnings during bootstrapping and regular configuration
if ((defined $Kolab::config{"bootstrap_config"}) &&
($Kolab::config{"bootstrap_config"} eq "true")) {
print $stream "$cc=================================================================\n";
print $stream "$cc This is a preliminary version of this configuration file and\n";
print $stream "$cc only used for bootstrapping. If you see this warning in your\n";
print $stream "$cc configuration after bootstrapping the Kolab Server\n";
print $stream "$cc SOMETHING WENT VERY WRONG !!!\n";
print $stream "$cc=================================================================\n";
} else {
print $stream "$cc=================================================================\n";
print $stream "$cc THIS FILE IS AUTOMATICALLY WRITTEN BY THE KOLAB CONFIG BACKEND.\n";
print $stream "$cc MANUAL CHANGES ARE LOST UNLESS MADE IN THE TEMPLATE FILE:\n";
print $stream "$cc\n";
print $stream "$cc $templateFile\n";
print $stream "$cc\n";
print $stream "$cc Changes can be activated by running ".$Kolab::config{'kolabconf_script'}."\n";
print $stream "$cc=================================================================\n";
}
}
sub build {
my $tmpl = shift;
my $cfg = shift;
my $owner = shift;
my $perm = shift;
my $cchr = shift; # comment character
my $templatedir = $Kolab::config{"templatedir"};
Kolab::log('T', "Creating new configuration file `$cfg' from template `$tmpl'", KOLAB_DEBUG );
my $template;
if (!($template = IO::File->new($tmpl, 'r'))) {
Kolab::log('T', "Unable to open template file `$tmpl': $!", KOLAB_ERROR);
# Error, fail gracefully
return;
}
my $config;
if (!($config = new File::Temp( TEMPLATE => 'tmpXXXXX',
DIR => $Kolab::config{"kolabdir"},
SUFFIX => '.kolabtmp',
UNLINK => 0 ))) {
Kolab::log('T', "Unable to open configuration file `$cfg': $!", KOLAB_ERROR);
exit(1);
}
my $skip = 0;
my $keep = 0;
while (<$template>) {
#Eat the meta data sections
if (/^KOLAB_META_START$/) {
my $found_end;
while (!$found_end) {
$_ = <$template>;
$found_end = /^KOLAB_META_END$/;
}
$_ = <$template>;
}
if (/\@{3}if\s+exists\(\s*(\S+?)\s*\)\@{3}/) {
# @@@if exists(/full/path/to/file)@@@
# also possible: @@@if exists( /full/path/to/file )@@@
if (-f $1) {
# Keep text if searched file or symbolic link exists.
$keep = 1;
} else {
# Skip text
$skip++;
$keep = 0;
}
} elsif (/\@{3}if\s+(\S+?)\@{3}/) {
# @@@if some_variable@@@
# The some_variable is a key in the $Kolab::config hash and has
# its value set to either 'false' or 'true'
if ($Kolab::config{$1} && lc($Kolab::config{$1}) ne "false" ) {
# Keep text
$keep = 1;
} else {
# Skip text
$skip++;
$keep = 0;
}
s/\@{3}if (\S+?)\@{3}\n?//;
} elsif (/\@{3}else\@{3}/) {
# @@@else@@@
if( $keep == 0 ) {
# Now keep
$keep = 1;
$skip--;
} else {
# Now skip
$keep = 0;
$skip++;
}
s/\@{3}else\@{3}\n?//;
} elsif (/\@{3}endif\@{3}/) {
# @@@endif@@@
($skip > 0) && $skip--;
s/\@{3}endif\@{3}\n?//;
} elsif (/\@{3}warning\@{3}/) {
# @@@warning@@@
printWarning($config, $tmpl, $cchr);
} elsif (/\@{3}print\s+([^\s()]+?)\s*\(([^,]+)?\)\@{3}/) {
# @@@print func([arg])@@@
my $val;
if ($1 eq 'getLDAPReplicas') {$val = getLDAPReplicas();}
elsif ($1 eq 'getLDAPAccess') {$val = getLDAPAccess();}
elsif ($1 eq 'getCyrusGroups') {$val = getCyrusGroups();}
elsif ($1 eq 'getPostfixMap') {$val = getPostfixMap($2);}
else {Kolab::log('T', "Unknown printable value `$1'", KOLAB_WARN);}
s/\@{3}print\s+(\S+?)\@{3}//;
($skip == 0) && print $config $val;
} else {
while (/\@{3}([^\s\@]+?)(\|(.+?)\((.*)\))?\@{3}/) {
# @@@attr@@@
# @@@attr|function(args)@@@
my $attr = $1;
my $fct = $3;
my $args = $4;
#print STDERR "attr=\"$attr\", fct=\"$fct\", args=\"$args\"\n";
if ($Kolab::config{$attr}) {
my $val = "";
if( !$fct ) {
if (ref $Kolab::config{$attr} eq "ARRAY") {
$val = $Kolab::config{$attr}->[0];
} else {
$val = $Kolab::config{$attr};
}
} else {
# Modifier functions
SWITCH: {
# Join function
$fct eq 'join' && do {
if (ref $Kolab::config{$attr} eq "ARRAY") {
my @vals = @{$Kolab::config{$attr}} ;
# We want to make sure subdomain.domain.tld comes before domain.tld
my @length_sorted_vals = sort {length $b cmp length $a} @vals;
$val = join ($args, @length_sorted_vals) ;
} else {
$val = $Kolab::config{$attr};
}
last SWITCH;
};
# Quote function
$fct eq 'quote' && do {
# slapd.conf compatible quoting
$val = $Kolab::config{$attr};
$val =~ s/"/\"/g;
$val = '"'.$val.'"';
last SWITCH;
}
}
}
s/\@{3}([^\s\@]+?)(\|.+?)?\@{3}/$val/;
last if ( $val eq "\@\@\@$attr\@\@\@" ); # prevent endless loop
} else {
# Only warn the user in case we are not skipping the section
($skip == 0) && Kolab::log('T', "No configuration variable corresponding to `$1' exists", KOLAB_WARN);
s/\@{3}([^\s\@]+?)\@{3}//;
}
}
($skip == 0) && print $config $_;
}
}
$template->close;
$config->close;
if (-f $cfg) {
my $cfgtemp = $config->filename;
my $rc = `diff -q $cfg $cfgtemp`;
chomp($rc);
if ($rc) {
Kolab::log('T', "`$cfg' change detected: $rc", KOLAB_DEBUG );
$confighaschanged{$tmpl} = 1;
#making backup
my $cfgbackup = $cfg . '.old';
my $oldmask = umask 077;
move($cfg, $cfgbackup) || Kolab::log('T', "Error backuping configfile to $cfgbackup, error: $!", KOLAB_ERROR );
# To avoid warnings, the backup files must be owned by root
chown(0, 0, $cfgbackup);
umask $oldmask;
}
} else {
Kolab::log('T', "`$cfg' creation detected", KOLAB_DEBUG );
$confighaschanged{$tmpl} = 1;
}
if($confighaschanged{$tmpl}) {
move($config->filename, $cfg) || Kolab::log('T', "Error moving configfile to $cfg, error: $!", KOLAB_ERROR );
fixup( $cfg, $owner, $perm );
} else {
unlink($config->filename);
}
Kolab::log('T', "Finished creating configuration file `$cfg'", KOLAB_DEBUG );
}
sub getPostfixMap
{
my $map = shift;
my $ret = '';
Kolab::log('T', "Building Postfix $map map", KOLAB_DEBUG);
my $ldap = Kolab::LDAP::create(
$Kolab::config{'ldap_ip'},
$Kolab::config{'ldap_port'},
$Kolab::config{'bind_dn'},
$Kolab::config{'bind_pw'}
);
my $mesg = $ldap->search(
base => 'k=kolab,'.$Kolab::config{'base_dn'},
scope => 'base',
filter => '(objectclass=*)'
);
if ($mesg->code) {
Kolab::log('T', "Unable to locate Postfix $map map entries in LDAP", KOLAB_ERROR);
exit(1);
}
my $ldapobject;
if ($mesg->code <= 0) {
foreach $ldapobject ($mesg->entries) {
my $routes = $ldapobject->get_value("postfix-$map", asref => 1);
foreach (@$routes) {
$_ = trim($_);
Kolab::log('T', "Adding entry `$_' to $map");
$ret .= $_ . "\n";
}
}
} else {
Kolab::log('T', "No Postfix $map map entries found");
}
Kolab::LDAP::destroy($ldap);
Kolab::log('T', "Finished building Postfix $map map", KOLAB_DEBUG);
return $ret;
}
sub getCyrusGroups
{
my $ret ='';
Kolab::log('T', 'Building Cyrus groups', KOLAB_DEBUG);
my $ldap = Kolab::LDAP::create(
$Kolab::config{'ldap_ip'},
$Kolab::config{'ldap_port'},
$Kolab::config{'bind_dn'},
$Kolab::config{'bind_pw'}
);
my $mesg = $ldap->search(
base => $Kolab::config{'base_dn'},
scope => 'sub',
filter => '(&(mail=*)(objectclass=kolabgroupofnames))'
);
if ($mesg->code) {
Kolab::log('T', 'Unable to locate Cyrus groups in LDAP', KOLAB_ERROR);
exit(1);
}
my $ldapobject;
my $count = 60000;
if ($mesg->code <= 0) {
foreach $ldapobject ($mesg->entries) {
#my $group = $ldapobject->get_value('cn') . '@'.join('.',reverse(@dn)) . ":*:$count:";
my $group = lc($ldapobject->get_value('mail')).":*:$count:";
my $userlist = $ldapobject->get_value('member', asref => 1);
foreach (@$userlist) {
my $uid = $_;
my $umesg = $ldap->search( base => $uid,
scope => 'base',
filter => '(objectClass=*)' );
if ( $umesg && $umesg->code() <= 0 && $umesg->count() == 1 ) {
my $mail;
($mail = $umesg->entry(0)->get_value('mail')) or
($mail = $umesg->entry(0)->get_value('uid'));
$group .= lc($mail).',';
}
}
$group =~ s/,$//;
$ret .= $group . "\n";
Kolab::log('T', "Adding cyrus group `$group'");
$count++;
}
} else {
Kolab::log('T', 'No Cyrus groups found');
}
Kolab::LDAP::destroy($ldap);
Kolab::log('T', 'Finished building Cyrus groups', KOLAB_DEBUG );
return $ret;
}
sub getLDAPAccess
{
my $ret = '';
Kolab::log('T', 'Building LDAP access file', KOLAB_DEBUG);
my $global_acl = <<'EOS';
# Domain specific access
access to filter=(&(objectClass=kolabInetOrgPerson)(mail=*@@@@domain@@@)(|(!(alias=*))(alias=*@@@@domain@@@)))
by group/kolabGroupOfNames="cn=@@@domain@@@,cn=domains,cn=internal,@@@base_dn@@@" write
by * break
access to filter=(&(objectClass=kolabGroupOfNames)(mail=*@@@@domain@@@))
by group/kolabGroupOfNames="cn=@@@domain@@@,cn=domains,cn=internal,@@@base_dn@@@" write
by * break
access to filter=(&(objectClass=kolabSharedFolder)(cn=*@@@@domain@@@))
by group/kolabGroupOfNames="cn=@@@domain@@@,cn=domains,cn=internal,@@@base_dn@@@" write
by * break
EOS
my $dom_acl1 = << 'EOS';
# Access to domain groups
access to dn.children="cn=domains,cn=internal,@@@base_dn@@@"
by group/kolabGroupOfNames="cn=admin,cn=internal,@@@base_dn@@@" write
by group/kolabGroupOfNames="cn=maintainer,cn=internal,@@@base_dn@@@" write
by dn="cn=nobody,cn=internal,@@@base_dn@@@" read
EOS
my $dom_acl2 = << 'EOS';
by group/kolabGroupOfNames="cn=@@@domain@@@,cn=domains,cn=internal,@@@base_dn@@@" read
EOS
my $dom_acl3 = << 'EOS';
by * search stop
EOS
my $str;
my $domain;
my @domains;
if( ref($Kolab::config{'postfix-mydestination'}) eq 'ARRAY' ) {
@domains = @{$Kolab::config{'postfix-mydestination'}};
} else {
@domains =( $Kolab::config{'postfix-mydestination'} );
}
($str = $dom_acl1) =~ s/\@{3}base_dn\@{3}/$Kolab::config{'base_dn'}/g;
$ret .= $str;
foreach $domain (@domains) {
($str = $dom_acl2) =~ s/\@{3}domain\@{3}/$domain/g;
$str =~ s/\@{3}base_dn\@{3}/$Kolab::config{'base_dn'}/g;
$ret .= $str;
}
($str = $dom_acl3) =~ s/\@{3}base_dn\@{3}/$Kolab::config{'base_dn'}/g;
$ret .= $str;
foreach $domain (@domains) {
($str = $global_acl) =~ s/\@{3}domain\@{3}/$domain/g;
$str =~ s/\@{3}base_dn\@{3}/$Kolab::config{'base_dn'}/g;
$ret .= $str;
Kolab::log('T', "Adding acl for domain '$str'");
}
return $ret;
}
sub getLDAPReplicas
{
my $ret = '';
Kolab::log('T', 'Building LDAP replicas', KOLAB_DEBUG);
# directory_mode syncrepl is supported from openldap-2.3.x and beyond
if ($Kolab::config{'directory_mode'} eq "syncrepl") {
if ( $Kolab::config{'is_master'} eq "false" ) {
# Output a syncrepl statement for database synchronisation
$ret .= "syncrepl rid=0 \n"
." provider=".$Kolab::config{"ldap_master_uri"}."\n"
." type=refreshAndPersist\n"
." retry=\"60 10 300 +\"\n"
." searchbase=\"".$Kolab::config{'base_dn'}."\"\n"
." scope=sub\n"
." schemachecking=on\n"
." binddn=\"".$Kolab::config{"bind_dn"}."\"\n"
." credentials=\"".$Kolab::config{"bind_pw"}."\"\n"
." bindmethod=simple\n";
}
} else {
if( $Kolab::config{'is_master'} eq "true" ) {
# Master setup
my @kh;
if( ref $Kolab::config{'kolabhost'} eq 'ARRAY' ) {
@kh = @{$Kolab::config{'kolabhost'}};
} else {
@kh = ( $Kolab::config{'kolabhost'} );
}
for my $h ( @kh ) {
next if lc($h) eq lc($Kolab::config{'fqdnhostname'});
$ret .= "replica uri=ldaps://$h\n"
." binddn=\"".$Kolab::config{'bind_dn'}."\"\n"
." bindmethod=simple credentials=".$Kolab::config{'bind_pw'}."\n\n";
}
} else {
# Slave setup
# Output an update dn statement instead
$ret .= "updatedn ".$Kolab::config{'bind_dn'}."\n";
$ret .= "updateref ".$Kolab::config{'ldap_master_uri'}."\n";
}
}
Kolab::log('T', 'Finished building LDAP replicas', KOLAB_DEBUG);
return $ret;
}
sub replaceMetaVar
{
my $var = shift;
while ($var =~ /\@{3}([^\s\@]+?)\@{3}/) {
my $attr = $1;
if ($Kolab::config{$attr}) {
my $val = $Kolab::config{$attr};
$var =~ s/\@{3}([^\s\@]+?)\@{3}/$val/;
} else {
Kolab::log('T', "No configuration variable corresponding to `$1' exists", KOLAB_WARN);
}
}
return $var;
}
sub loadMetaTemplates
{
my $templatedir = shift;
my ($tref, $pref, $oref, $cmdref, $ccharref) = @_;
Kolab::log('T', 'Collecting template files', KOLAB_DEBUG );
opendir(DIR, $templatedir) or Kolab::log('T', 'Given templatedir $templatedir does not exist!', KOLAB_ERROR );
my @metatemplates = grep { /\.template$/ } readdir (DIR);
closedir(DIR);
foreach my $template (@metatemplates) {
my $runonchange = undef;
my $commentchar = undef;
#Open each file and check for the META
if (open (TEMPLATE, "$templatedir/$template" )) {
my $line = <TEMPLATE>;
if ($line =~ /^KOLAB_META_START$/) {
Kolab::log('T', 'Processing META template :'.$template, KOLAB_DEBUG );
my ($found_end, $target, $permissions, $ownership);
while (<TEMPLATE>) {
$line = $_;
if (!$found_end) {
$found_end = $line =~ /^KOLAB_META_END$/;
if (!$found_end && $line) {
my ($key,$value) = split(/=/,$line);
chomp($value);
Kolab::log('T', 'META Key: '.$key.' Value: '.$value, KOLAB_DEBUG );
if ($key =~ /^TARGET$/) {
$target = replaceMetaVar($value);
Kolab::log('T', 'META Target '.$target, KOLAB_DEBUG );
} elsif ($key =~ /^PERMISSIONS$/) {
$permissions = replaceMetaVar($value);
Kolab::log('T', 'META Permissions '.$permissions, KOLAB_DEBUG );
} elsif ($key =~ /^OWNERSHIP$/) {
$ownership = replaceMetaVar($value);
Kolab::log('T', 'META Ownership '.$ownership, KOLAB_DEBUG );
} elsif ($key =~ /^RUNONCHANGE$/) {
$runonchange = replaceMetaVar($value);
Kolab::log('T', 'META Cmd to execute '.$runonchange, KOLAB_DEBUG );
} elsif ($key =~ /^COMMENT_CHAR$/) {
$commentchar = replaceMetaVar($value);
Kolab::log('T', 'META CommentChar to use: '.$commentchar, KOLAB_DEBUG );
} else {
Kolab::log('T', 'incorrect META key "'.$key.'" in: '.$template, KOLAB_WARN );
}
}
}
}
if ($found_end && $target && $permissions && $ownership) {
Kolab::log('T', 'All mandatory fields populated in '.$template, KOLAB_DEBUG );
$$tref{$templatedir . "/" . $template} = $target;
$$oref{$target} = $ownership;
$permissions = oct($permissions);
$$pref{$target} = $permissions;
my $runcmdtemplate = $templatedir."/".$template;
$$cmdref{$runcmdtemplate} = $runonchange if (defined $runonchange);
$$ccharref{$target} = $commentchar if (defined $commentchar);
}
}
} else {
Kolab::log('T', 'Could not open template file: '. $template, KOLAB_WARN);
}
}
}
sub rebuildTemplates
{
my %args = @_;
$args{doreload} = 1 if !exists $args{doreload};
$args{dorunonchange} = 1 if !exists $args{dorunonchange};
#$args{templates} = ALL if !exists $args{templates};
my $key;
my $value;
my $section="";
my %runonchange;
my $templatedir = $Kolab::config{"templatedir"};
Kolab::log('T', 'Regenerating configuration files', KOLAB_DEBUG );
Kolab::log('T', 'Loading meta-template data', KOLAB_DEBUG );
loadMetaTemplates( $templatedir, \%templates, \%permissions, \%ownership, \%runonchange, \%commentchar );
# defaults to all templates
$args{templates} = [ keys %templates ] if !exists $args{templates};
my $cfg;
my $tpl;
foreach $tpl (@{$args{templates}}) {
$cfg = $templates{$tpl};
build($tpl, $cfg, $ownership{$cfg}, $permissions{$cfg}, $commentchar{$cfg});
}
Kolab::log('T', 'Finished regenerating configuration files', KOLAB_DEBUG );
if(!$args{dorunonchange}) {
Kolab::log('T', 'RUNONCHANGE will not be executed, as requested.', KOLAB_DEBUG );
return;
}
my %cmds = ();
foreach $key (keys %runonchange) {
if (defined $confighaschanged{$key}) {
Kolab::log('T', 'Queueing RUNONCHANGE for '.$key, KOLAB_DEBUG );
$cmds{$runonchange{$key}} = 1;
}
}
my $cmd;
foreach $cmd (keys %cmds) {
# $cmd can contain:
# - /usr/sbin/postmap: should always be executed
# - openpkg rc imapd restart (in openpkg distribution)
# - kolabsrv rc post reload (in other distributions)
# The commands with ' rc ' may only be executed when reloading is not
# prohibited by the user with the "-n" option.
if ($args{doreload} || $cmd !~ / rc \S+ re(start|load)/) {
Kolab::log('T', 'Executing command: '.$cmd, KOLAB_DEBUG );
system($cmd);
} else {
Kolab::log('T', 'Reload not allowed, not executing command: '.$cmd, KOLAB_DEBUG );
}
}
}
sub checkPermissions {
my $key;
my $value;
my $templatedir = $Kolab::config{"templatedir"};
Kolab::log('T', 'Checking generated config file permissions and ownership', KOLAB_DEBUG );
loadMetaTemplates( $templatedir, \%templates, \%permissions, \%ownership );
my $ok = 1;
foreach $key (keys %templates) {
my $tpl = $templates{$key};
if (-r $tpl) {
my $st = stat($tpl);
my $owner = getpwuid($st->uid).':'.getgrgid($st->gid);
if( ( ($st->mode & 07777) != $permissions{$tpl}) ||
($owner ne $ownership{$tpl}) ) {
my $str = 'File '.$tpl.' has the wrong persmissions/owner. Found '
.sprintf("%lo", $st->mode&07777).' '.$owner.', expected '
.sprintf("%lo",$permissions{$tpl}).' '.$ownership{$tpl};
print( "$str\n" );
Kolab::log('T', $str, KOLAB_ERROR );
$ok = 0;
}
} else {
my $str = "File $tpl does not exist";
print "$str\n";
Kolab::log('T', "$str", KOLAB_ERROR );
}
}
return $ok;
}
1;
__END__
=head1 NAME
Kolab::Conf - Perl extension for Kolab template generation
=head1 ABSTRACT
Kolab::Conf handles the generation of template files, used by
kolabconf.
=head1 COPYRIGHT AND AUTHORS
Stuart Bingë and others (see AUTHORS file)
=head1 LICENSE
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, 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 can view the GNU General Public License, online, at the GNU
Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
=cut
--- NEW FILE: Cyrus.pm ---
package Kolab::Cyrus;
## COPYRIGHT
## ---------
##
## See AUTHORS file
##
##
## LICENSE
## -------
##
## 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, 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 can view the GNU General Public License, online, at the GNU
## Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
##
## $Revision: 1.1 $
use 5.008;
use strict;
use warnings;
use Cyrus::IMAP::Admin;
use Kolab::Util;
use Kolab;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
'all' => [ qw(
&create
&createUid
&createMailbox
&deleteMailbox
&setQuota
&setACL
) ]
);
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
);
our $VERSION = '0.9';
sub create
{
Kolab::log('Y', 'Connecting to local Cyrus admin interface');
my $cyrus = Cyrus::IMAP::Admin->new($Kolab::config{'connect_addr'});
if (!$cyrus) {
Kolab::log('Y', 'Unable to connect to local Cyrus admin interface', KOLAB_ERROR);
return 0;
}
if (!$cyrus->authenticate(
'User' => $Kolab::config{'cyrus_admin'},
'Password' => $Kolab::config{'cyrus_admin_pw'},
'Mechanism' => 'LOGIN',
)) {
Kolab::log('Y', "Unable to authenticate with Cyrus admin interface, Error = `" . $cyrus->error . "'", KOLAB_ERROR);
return 0;
}
return $cyrus;
}
sub createUid
{
my $user = shift;
my $sf = shift || 0;
my $seperator = '/';
my $uidprefix = 'user';
if ($sf) {
$seperator = '.';
$uidprefix = 'shared';
}
return $uidprefix . $seperator . $user;
# return 'user' . ($sf ? '.' : '/') . $user;
}
sub createMailbox
{
my $cyrus = shift;
my $uid = shift;
my $sf = shift || 0;
my $partition = shift || '';
my $cyruid = &createUid($uid, $sf);
my $mailbox = ($cyrus->list($cyruid))[0];
if ($uid && ($uid ne $Kolab::config{'cyrus_admin'}) && ($uid ne "freebusy") && ($uid ne "nobody") && !defined($mailbox)) {
Kolab::log('Y', "Creating mailbox `$cyruid' on ".($partition?"partition `$partition'":"default partition"));
if (!$cyrus->create($cyruid, $partition)) {
Kolab::log('Y', "Unable to create mailbox `$cyruid', Error = `" . $cyrus->error . "'", KOLAB_WARN);
}
} else {
Kolab::log('Y', "Skipping mailbox creation for $uid (curuid='$cyruid', mailbox='".join(',',@{$mailbox})."'", KOLAB_DEBUG);
}
}
sub setQuota
{
my $cyrus = shift;
my $uid = shift;
my $quota = shift || 0;
my $sf = shift || 0;
my $cyruid = &createUid($uid, $sf);
if( $quota < 0 ) {
return;
}
(my $root, my %quota) = $cyrus->quotaroot($cyruid);
my $setquota = $quota{'STORAGE'}[1];
if (!defined($setquota) || ($setquota != $quota)) {
if( $quota == 0 ) {
Kolab::log('Y', "Removing quota from mailbox `$cyruid'");
if (!$cyrus->setquota($cyruid)) {
Kolab::log('Y', "Unable to remove quota for mailbox `$cyruid', Error = `" . $cyrus->error . "'", KOLAB_WARN);
}
} else {
Kolab::log('Y', "Setting quota of mailbox `$cyruid' to $quota");
if (!$cyrus->setquota($cyruid, 'STORAGE', $quota)) {
Kolab::log('Y', "Unable to set quota for mailbox `$cyruid', Error = `" . $cyrus->error . "'", KOLAB_WARN);
}
}
}
}
sub deleteMailbox
{
my $cyrus = shift;
my $uid = shift;
my $sf = shift || 0;
my $cyruid = &createUid($uid, $sf);
Kolab::log('Y', "Removing mailbox `$cyruid'");
if (!$cyrus->setacl($cyruid, $Kolab::config{'cyrus_admin'}, 'c')) {
Kolab::log('Y', "Unable to reset ACL of mailbox `$cyruid', Error = `" . $cyrus->error . "'", KOLAB_WARN);
}
if (!$cyrus->delete($cyruid)) {
Kolab::log('Y', "Unable to remove mailbox `$cyruid', Error = `" . $cyrus->error . "'", KOLAB_WARN);
}
}
sub setACL
{
my $cyrus = shift;
my $uid = shift;
my $sf = shift || 0;
my $cyruid = &createUid($uid, $sf);
Kolab::log('Y', "Setting up ACL of mailbox `$cyruid'");
my %acls = $cyrus->listacl( $cyruid );
my ($user, $entry, $acl);
Kolab::log('Y', "Removing users from ACL of $cyruid (users are \"".join(', ', keys %acls)."\")", KOLAB_DEBUG);
foreach $user ( keys %acls) {
Kolab::log('Y', "Removing `$user' from the ACL of mailbox `$cyruid'");
if (!$cyrus->deleteacl($cyruid, $user)) {
Kolab::log('Y', "Unable to remove `$user' from the ACL of mailbox `$cyruid', Error = `" . $cyrus->error . "'", KOLAB_WARN);
}
}
Kolab::log('Y', "Add users from ACL of $cyruid", KOLAB_DEBUG);
my $newacl = shift;
foreach $entry (@$newacl) {
Kolab::log('Y', "Setting up ACL `$entry'", KOLAB_DEBUG);
($user, $acl) = split(/ /, $entry , 2);
Kolab::log('Y', "Split `$user' and `$acl'", KOLAB_DEBUG);
$user = trim($user);
$acl = trim($acl);
Kolab::log('Y', "Setting the ACL of user `$user' in mailbox `$cyruid' to $acl");
if (!$cyrus->setacl($cyruid, $user, $acl)) {
Kolab::log('Y', "Unable to set the ACL of user `$user' in mailbox `$cyruid' to $acl, Error = `" . $cyrus->error . "'", KOLAB_WARN);
}
}
Kolab::log('Y', "Finished modifying ACL of $cyruid", KOLAB_DEBUG);
}
sub setFolderType {
my $cyrus = shift;
my $uid = shift;
my $sf = shift || 0;
my $foldertype = shift || 'mail';
my $cyruid = &createUid($uid, $sf);
if (!$cyrus->mboxconfig($cyruid, '/vendor/kolab/folder-type', $foldertype)) {
Kolab::log('Y', "Unable to set the folder type for mailbox `$cyruid' to `$foldertype', Error = `" . $cyrus->error . "'", KOLAB_WARN);
}
}
1;
__END__
# Below is stub documentation for your module. You'd better edit it!
=head1 NAME
Kolab::Cyrus - Perl extension for interfacing with the Kolab Cyrus
admin module.
=head1 ABSTRACT
Kolab::Cyrus contains cyrus-related functions, such as
adding/deleting mailboxes, etc.
=head1 COPYRIGHT AND AUTHORS
Stuart Bingë and others (see AUTHORS file)
=head1 LICENSE
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, 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 can view the GNU General Public License, online, at the GNU
Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
=cut
--- NEW FILE: LDAP.pm ---
package Kolab::LDAP;
## COPYRIGHT
## ---------
##
## See AUTHORS file
##
##
## LICENSE
## -------
##
## 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, 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
[...1006 lines suppressed...]
=head1 COPYRIGHT AND AUTHORS
Stuart Bingë and others (see AUTHORS file)
=head1 LICENSE
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, 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 can view the GNU General Public License, online, at the GNU
Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
=cut
--- NEW FILE: Util.pm ---
package Kolab::Util;
## COPYRIGHT
## ---------
##
## See AUTHORS file
##
##
## LICENSE
## -------
##
## 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, 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 can view the GNU General Public License, online, at the GNU
## Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
##
## $Revision: 1.1 $
use 5.008;
use strict;
use warnings;
use IO::File;
use Sys::Syslog;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
'all' => [ qw(
) ]
);
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
&trim
&ldapDateToEpoch
&readConfig
&readList
&superLog
);
our $VERSION = '0.9';
sub trim
{
my $string = shift;
if (defined $string) {
$string =~ s/^\s+//g;
$string =~ s/\s+$//g;
chomp $string;
}
return $string;
}
sub ldapDateToEpoch
{
my $ldapdate = shift;
(my $y, my $m, my $d, my $h, my $mi, my $se) = unpack('A4A2A2A2A2A2', $ldapdate);
return timelocal($se, $mi, $h, $d, $m, $y);
}
sub superLog
{
my $text = shift;
#print STDERR "$text\n";
syslog('info', "$text");
}
sub readConfig
{
my $ref = shift;
my (%cfg, $file);
if (ref($ref) eq 'HASH') {
%cfg = %$ref;
$file = shift || 0;
} else {
$file = $ref;
}
if (!$file) { return %cfg; }
my $sep = shift || ':';
$sep = '\s' if ($sep eq ' ' || $sep eq '#');
my $fd;
if (!($fd = IO::File->new($file, 'r'))) {
superLog( "Warning: Could not read $file");
return %cfg;
}
foreach (<$fd>) {
if (/^([^$sep#]+)$sep(.*)/) {
$cfg{trim($1)} = trim($2);
}
}
return %cfg;
}
sub readList
{
my @list;
my $file = shift || 0;
if (!$file) { return @list; }
my $fd;
if (!($fd = IO::File->new($file, 'r'))) { return @list; }
foreach (<$fd>) {
if (/^([^#]+)/) {
my $temp = trim($1);
next if $temp eq '';
push(@list, ($temp));
}
}
return @list;
}
1;
__END__
# Below is stub documentation for your module. You'd better edit it!
=head1 NAME
Kolab::Util - Perl extension for general utility functions
=head1 ABSTRACT
Kolab::Util contains several basic utility functions.
=head1 COPYRIGHT AND AUTHORS
Stuart Bingë and others (see AUTHORS file)
=head1 LICENSE
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, 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 can view the GNU General Public License, online, at the GNU
Project's homepage; see <http://www.gnu.org/licenses/gpl.html>.
=cut
- Previous message: gunnar: server/perl-kolab/perl-kolab/bin .cvsignore, NONE, 1.1 kolab_smtpdpolicy.in, NONE, 1.1 kolabdcachetool.in, NONE, 1.1 kolabpasswd.in, NONE, 1.1 kolabquotareport.in, NONE, 1.1 kolabquotawarn.in, NONE, 1.1
- Next message: gunnar: server/perl-kolab/perl-kolab/lib/Kolab/LDAP/Backend ad.pm, NONE, 1.1 fds.pm, NONE, 1.1 slurpd.pm, NONE, 1.1 syncrepl.pm, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the commits
mailing list