summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Kolab.pm67
-rw-r--r--lib/Kolab/Conf.pm9
-rw-r--r--lib/Kolab/Cyrus.pm70
-rw-r--r--lib/Kolab/LDAP.pm460
-rw-r--r--lib/Kolab/LDAP/Backend.pm8
-rw-r--r--lib/Kolab/LDAP/Backend/ad.pm174
-rw-r--r--lib/Kolab/LDAP/Backend/fds.pm191
-rw-r--r--lib/Kolab/LDAP/Backend/slurpd.pm148
-rw-r--r--lib/Kolab/LDAP/Backend/syncrepl.pm430
-rw-r--r--lib/Kolab/Util.pm6
10 files changed, 797 insertions, 766 deletions
diff --git a/lib/Kolab.pm b/lib/Kolab.pm
index 0445bd4..0c743bf 100644
--- a/lib/Kolab.pm
+++ b/lib/Kolab.pm
@@ -41,7 +41,7 @@ our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
'all' => [ qw(
%config
- $reloadOk
+ $reloadOk
&reloadConfig
&reload
&log
@@ -103,7 +103,7 @@ sub reloadConfig
# Return if we should only read the base information.
if ($globals_only) {
- return;
+ return;
}
# Determine the root of the kolab installation, and read `kolab.globals'
@@ -114,8 +114,8 @@ sub reloadConfig
$tempval = (getpwnam($config{'kolab_musr'}))[7];
if (! defined $tempval) {
$config{'log_level'} = KOLAB_WARN;
- &log('C', 'Unable to determine the kolab user main directory', KOLAB_ERROR);
- $error = 1;
+ &log('C', 'Unable to determine the kolab user main directory', KOLAB_ERROR);
+ $error = 1;
}
# Now read `kolab.conf', overwriting values read from `kolab.globals'
@@ -130,56 +130,56 @@ sub reloadConfig
$config{'kolab_uid'} = (getpwnam($config{'kolab_musr'}))[2];
if (!defined $config{'kolab_uid'}) {
&log('C', "Unable to determine the uid of user '$config{'kolab_musr'}'", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
$config{'kolab_gid'} = (getgrnam($config{'kolab_mgrp'}))[2];
if (!defined $config{'kolab_gid'}) {
&log('C', "Unable to determine the gid of user '$config{'kolab_mgrp'}'", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
$config{'kolab_n_uid'} = (getpwnam($config{'kolab_usr'}))[2];
if (!defined $config{'kolab_n_uid'}) {
&log('C', "Unable to determine the uid of user '$config{'kolab_usr'}", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
$config{'kolab_n_gid'} = (getgrnam($config{'kolab_grp'}))[2];
if (!defined $config{'kolab_n_gid'}) {
&log('C', "Unable to determine the gid of user $config{'kolab_grp'}", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
$config{'kolab_r_uid'} = (getpwnam($config{'kolab_rusr'}))[2];
if (!defined $config{'kolab_r_uid'}) {
&log('C', "Unable to determine the uid of user '$config{'kolab_rusr'}'", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
$config{'kolab_r_gid'} = (getgrnam($config{'kolab_rgrp'}))[2];
if (!defined $config{'kolab_r_gid'}) {
&log('C', "Unable to determine the gid of user '$config{'kolab_rgrp'}'", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
# Make sure the critical variables we need were defined in kolab.conf
if (!exists $config{'bind_dn'} || !exists $config{'bind_pw'} || !exists $config{'ldap_uri'} || !exists $config{'base_dn'}) {
&log('C', "One or more required configuration variables (`bind_dn', `bind_pw', `ldap_uri' and/or `base_dn') are missing in `kolab.conf'", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
# Make a hash of the bind password available too
if( !exists $config{'bind_pw_hash'} ) {
- my $hashcmd = $config{'hashmethod'} . " '".$config{'bind_pw'}."'";
- $config{'bind_pw_hash'} = `$hashcmd`;
- chomp($config{'bind_pw_hash'});
+ my $hashcmd = $config{'hashmethod'} . " '".$config{'bind_pw'}."'";
+ $config{'bind_pw_hash'} = `$hashcmd`;
+ chomp($config{'bind_pw_hash'});
}
# Retrieve the LDAP values of the main kolab object to complete our config hash
if (!($tempval = URI->new($config{'ldap_uri'}))) {
&log('C', "Unable to parse ldap_uri `" . $config{'ldap_uri'} . "'", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
} else {
$config{'ldap_ip'} = $tempval->host;
$config{'ldap_port'} = $tempval->port;
@@ -196,13 +196,13 @@ sub reloadConfig
if (!($ldap = Net::LDAP->new($config{'ldap_uri'}, verify => 'none' ))) {
&log('C', "Unable to connect to LDAP server `" . $config{'ldap_ip'} . ":" . $config{'ldap_port'} . "'", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
$mesg = $ldap->bind($config{'bind_dn'}, password => $config{'bind_pw'}) if $ldap;
if ($ldap && $mesg->code) {
&log('C', "Unable to bind to DN `" . $config{'bind_dn'} . "'", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
#$ldap = Kolab::LDAP::create(
@@ -221,20 +221,20 @@ sub reloadConfig
if (!$mesg->code) {
$ldapobject = $mesg->pop_entry;
foreach $tempval ($ldapobject->attributes) {
- my $vals = $ldapobject->get_value($tempval, asref => 1 );
- if( !ref($vals) ) {
- # Not a ref at all???
- &log('C', "Attribute $tempval does not exist", KOLAB_WARN );
- } elsif( @{$vals} == 1 ) {
- $config{lc($tempval)} = $vals->[0];
- } else {
- $config{lc($tempval)} = $vals;
- }
+ my $vals = $ldapobject->get_value($tempval, asref => 1 );
+ if( !ref($vals) ) {
+ # Not a ref at all???
+ &log('C', "Attribute $tempval does not exist", KOLAB_WARN );
+ } elsif( @{$vals} == 1 ) {
+ $config{lc($tempval)} = $vals->[0];
+ } else {
+ $config{lc($tempval)} = $vals;
+ }
}
} else {
&log('C', "Unable to find kolab object `" . $config{'kolab_dn'} . "'", KOLAB_ERROR);
# exit(1);
- $error = 1;
+ $error = 1;
}
} else {
&log('C', "Unable to read configuration data from LDAP", KOLAB_WARN);
@@ -283,7 +283,7 @@ sub reloadConfig
if (($config{'directory_mode'} eq 'syncrepl') && !defined $config{'syncrepl_cookie_file'}) {
&log('C', "Configuration variable `syncrepl_cookie_file' is missing ".
"in `kolab.globals' or `kolab.globals' while using `syncrepl' directory_mode", KOLAB_ERROR);
- $error = 1;
+ $error = 1;
}
# `conn_refresh_period' specifies how many minutes to wait before forceably
@@ -313,7 +313,7 @@ sub reloadConfig
if (!($tempval = URI->new($config{'user_ldap_uri'}))) {
&log('C', "Unable to parse user_ldap_uri `" . $config{'user_ldap_uri'} . "'", KOLAB_ERROR);
# exit(1);
- $error = 1;
+ $error = 1;
} else {
$config{'user_ldap_ip'} = $tempval->host;
$config{'user_ldap_port'} = $tempval->port;
@@ -342,12 +342,11 @@ sub reloadConfig
$config{'user_field_guid'} = 'objectGUID' if (!exists $config{'user_field_guid'});
$config{'user_field_quota'} = 'userquota' if (!exists $config{'user_field_quota'});
} else {
- # slurd/default
+ # slurpd/default
$config{'user_field_deleted'} = 'kolabdeleteflag' if (!exists $config{'user_field_deleted'});
$config{'user_field_modified'} = 'modifytimestamp' if (!exists $config{'user_field_modified'});
$config{'user_field_guid'} = 'entryUUID' if (!exists $config{'user_field_guid'});
$config{'user_field_quota'} = 'cyrus-userquota' if (!exists $config{'user_field_quota'});
-
}
# The `sf_XXX' variables are the shared folder equivalents of the `user_XXX' variables
@@ -356,7 +355,7 @@ sub reloadConfig
if (!($tempval = URI->new($config{'sf_ldap_uri'}))) {
&log('C', "Unable to parse sf_ldap_uri `" . $config{'sf_ldap_uri'} . "'", KOLAB_ERROR);
# exit(1);
- $error = 1;
+ $error = 1;
} else {
$config{'sf_ldap_ip'} = $tempval->host;
$config{'sf_ldap_port'} = $tempval->port;
@@ -383,14 +382,14 @@ sub reloadConfig
$config{'sf_field_quota'} = 'cyrus-userquota' if (!exists $config{'sf_field_quota'});
}
- # The `group_XXX' variables are the distribution list/groups
+ # The `group_XXX' variables are the distribution list/groups
# equivalents of the `user_XXX' variables
$config{'group_ldap_uri'} = $config{'ldap_uri'} if (!exists $config{'group_ldap_uri'});
if (!($tempval = URI->new($config{'group_ldap_uri'}))) {
&log('C', "Unable to parse group_ldap_uri `" . $config{'group_ldap_uri'} . "'", KOLAB_ERROR);
# exit(1);
- $error = 1;
+ $error = 1;
} else {
$config{'group_ldap_ip'} = $tempval->host;
$config{'group_ldap_port'} = $tempval->port;
diff --git a/lib/Kolab/Conf.pm b/lib/Kolab/Conf.pm
index 8ca62ca..69e39f6 100644
--- a/lib/Kolab/Conf.pm
+++ b/lib/Kolab/Conf.pm
@@ -227,7 +227,7 @@ sub build {
} else {
# Modifier functions
SWITCH: {
- # Join function
+ # Join function
$fct eq 'join' && do {
if (ref $Kolab::config{$attr} eq "ARRAY") {
my @vals = @{$Kolab::config{$attr}} ;
@@ -260,11 +260,10 @@ sub build {
($skip == 0) && print $config $_;
}
}
-
+
$template->close;
$config->close;
-
if (-f $cfg) {
my $cfgtemp = $config->filename;
my $rc = `diff -q $cfg $cfgtemp`;
@@ -369,7 +368,7 @@ sub getCyrusGroups
foreach (@$userlist) {
my $uid = $_;
my $umesg = $ldap->search( base => $uid,
- scope => 'base',
+ scope => 'base',
filter => '(objectClass=*)' );
if ( $umesg && $umesg->code() <= 0 && $umesg->count() == 1 ) {
my $mail;
@@ -549,7 +548,7 @@ sub loadMetaTemplates
my ($found_end, $target, $permissions, $ownership);
while (<TEMPLATE>) {
$line = $_;
-
+
if (!$found_end) {
$found_end = $line =~ /^KOLAB_META_END$/;
if (!$found_end && $line) {
diff --git a/lib/Kolab/Cyrus.pm b/lib/Kolab/Cyrus.pm
index 4973add..f4462af 100644
--- a/lib/Kolab/Cyrus.pm
+++ b/lib/Kolab/Cyrus.pm
@@ -63,7 +63,7 @@ sub create
if (!$cyrus) {
Kolab::log('Y', 'Unable to connect to local Cyrus admin interface', KOLAB_ERROR);
- return 0;
+ return 0;
}
if (!$cyrus->authenticate(
@@ -72,7 +72,7 @@ sub create
'Mechanism' => 'LOGIN',
)) {
Kolab::log('Y', "Unable to authenticate with Cyrus admin interface, Error = `" . $cyrus->error . "'", KOLAB_ERROR);
- return 0;
+ return 0;
}
return $cyrus;
@@ -84,10 +84,10 @@ sub createUid
my $sf = shift || 0;
my $seperator = '/';
my $uidprefix = 'user';
- if ($sf) {
- $seperator = '.';
+ if ($sf) {
+ $seperator = '.';
$uidprefix = 'shared';
- }
+ }
return $uidprefix . $seperator . $user;
# return 'user' . ($sf ? '.' : '/') . $user;
}
@@ -124,21 +124,21 @@ sub createCalendar
my @mailboxes = $cyrus->list("user/$user/*\@$domain");
my %info;
foreach my $mailbox (@mailboxes) {
- my $u = @{$mailbox}[0];
- %info = $cyrus->info($u, ('/vendor/kolab/folder-type'));
- my $key = '/mailbox/{' . $u . '}/vendor/kolab/folder-type';
- if (exists($info{$key}) && $info{$key} eq 'event.default') {
- $calendar = $u;
- }
+ my $u = @{$mailbox}[0];
+ %info = $cyrus->info($u, ('/vendor/kolab/folder-type'));
+ my $key = '/mailbox/{' . $u . '}/vendor/kolab/folder-type';
+ if (exists($info{$key}) && $info{$key} eq 'event.default') {
+ $calendar = $u;
+ }
}
if ($calendar) {
Kolab::log('Y', "Skipping calendar creation for $user\@$domain as $calendar is a default calendar.", KOLAB_DEBUG);
} else {
Kolab::log('Y', "Creating default calendar for $user\@$domain.", KOLAB_DEBUG);
- createMailbox($cyrus, $folder, 0);
- setFolderType($cyrus, $folder, 0, 'event.default');
- setACL($cyrus, $folder, 0, $acl);
+ createMailbox($cyrus, $folder, 0);
+ setFolderType($cyrus, $folder, 0, 'event.default');
+ setACL($cyrus, $folder, 0, $acl);
Kolab::log('Y', "Successfully created default calendar for $user\@$domain.", KOLAB_DEBUG);
}
}
@@ -152,24 +152,24 @@ sub setQuota
my $cyruid = &createUid($uid, $sf);
if( $quota < 0 ) {
- return;
+ 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);
- }
- }
+ 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);
+ }
+ }
}
}
@@ -224,15 +224,15 @@ sub setACL
}
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);
- }
+ 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;
diff --git a/lib/Kolab/LDAP.pm b/lib/Kolab/LDAP.pm
index 8756be0..794e737 100644
--- a/lib/Kolab/LDAP.pm
+++ b/lib/Kolab/LDAP.pm
@@ -81,7 +81,7 @@ sub startup
Kolab::log('L', 'Starting up');
if (!$db_statedir && $statedir) {
- $db_statedir = $statedir;
+ $db_statedir = $statedir;
}
}
@@ -187,15 +187,15 @@ sub graveyardRessurect
my $oldgyarduid = $$gyard_db{$guid} || '';
if ($oldgyarduid) {
- # The object needs to be resurrected!
- if ($oldgyarduid ne $uid) {
- Kolab::log('L', "Resurrected object `$uid' already exists as `$oldgyarduid'; refusing to create", KOLAB_WARN);
- } else {
- Kolab::log('L', "Object `$uid' has been resurrected", KOLAB_DEBUG);
- }
- # Remove the object from the graveyard
- delete $$gyard_db{$guid};
- delete $$gyard_ts_db{$guid};
+ # The object needs to be resurrected!
+ if ($oldgyarduid ne $uid) {
+ Kolab::log('L', "Resurrected object `$uid' already exists as `$oldgyarduid'; refusing to create", KOLAB_WARN);
+ } else {
+ Kolab::log('L', "Object `$uid' has been resurrected", KOLAB_DEBUG);
+ }
+ # Remove the object from the graveyard
+ delete $$gyard_db{$guid};
+ delete $$gyard_ts_db{$guid};
}
graveyardClose(%$gyard_db, %$gyard_ts_db);
@@ -313,25 +313,25 @@ sub create
my $ldap;
if( $pt == 636 ) {
- # Use SSL
- $ldap = Net::LDAPS->new(
- $ip,
- port => $pt,
- version => 3,
- timeout => 20,
- async => $as,
- verify => 'none',
- onerror => \&ldap_error
- );
+ # Use SSL
+ $ldap = Net::LDAPS->new(
+ $ip,
+ port => $pt,
+ version => 3,
+ timeout => 20,
+ async => $as,
+ verify => 'none',
+ onerror => \&ldap_error
+ );
} else {
- $ldap = Net::LDAP->new(
- $ip,
- port => $pt,
- version => 3,
- timeout => 20,
- async => $as,
- onerror => \&ldap_error
- );
+ $ldap = Net::LDAP->new(
+ $ip,
+ port => $pt,
+ version => 3,
+ timeout => 20,
+ async => $as,
+ onerror => \&ldap_error
+ );
}
if (!$ldap) {
Kolab::log('L', "Unable to connect to LDAP server `$ip:$pt'", KOLAB_ERROR);
@@ -393,43 +393,45 @@ sub isDeleted
my $object = shift;
my $p = shift || 'user';
my $del = $object->get_value($Kolab::config{$p . '_field_deleted'}, asref => 1 );
- #foreach (@$del) {
- # return 1 if lc($_) eq lc($Kolab::config{'fqdnhostname'});
- #}
- #return 0;
+# foreach (@$del) {
+# return 1 if lc($_) eq lc($Kolab::config{'fqdnhostname'});
+# }
+# return 0;
return $#$del > 0;
}
# Map from Kolab ACLs to Cyrus ACLs
sub mapAcls {
- my $acls = shift;
- my $sf = shift || 0;
- my @acls = map {
- my ($uid,$perm) = split(/\s+/,$_,2);
- Kolab::log('L', "Kolab::LDAP::mapAcls() uid=$uid perm=$perm", KOLAB_DEBUG);
- my $post = 0;
- if( $perm =~ /(.*)\/post/ ) {
- $perm = $1;
- $post = 1;
+ my $acls = shift;
+ my $sf = shift || 0;
+ my @acls = map {
+ my ($uid,$perm) = split(/\s+/,$_,2);
+ Kolab::log('L', "Kolab::LDAP::mapAcls() uid=$uid perm=$perm", KOLAB_DEBUG);
+ my $post = 0;
+ if( $perm =~ /(.*)\/post/ ) {
+ $perm = $1;
+ $post = 1;
+ }
+ Kolab::log('L', "Kolab::LDAP::mapAcls() uid=$uid perm=$perm post=$post", KOLAB_DEBUG);
+ if( lc $perm eq 'none' ) { $_ = "$uid none"; }
+ elsif( lc $perm eq 'post' ) { $_ = "$uid p"; }
+ elsif( lc $perm eq 'read' ) { $_ = "$uid lrs"; }
+ elsif( lc $perm eq 'read anon' ) { $_ = "$uid lr"; }
+ elsif( lc $perm eq 'read hidden' ) { $_ = "$uid rs"; }
+ elsif( lc $perm eq 'append' ) { $_ = "$uid lrsip"; }
+ elsif( lc $perm eq 'write' ) { if( $sf ) { $_ = "$uid lrsiwdp"; } else { $_ = "$uid lrsiwcdp"; } }
+ elsif( lc $perm eq 'all' ) { if( $sf ) { $_ = "$uid lrsiwdap"; } else { $_ = "$uid lrsiwcdap"; } }
+ else { $_ = "$uid $perm"; } # passthrough
+
+ if( $post ) { $_ .= 'p'; }
+ Kolab::log('L', "Kolab::LDAP::mapAcls() acl=$_", KOLAB_DEBUG);
+ } @$acls;
+
+ if( $sf ) {
+ push(@$acls, "manager lrsiwcdap");
}
- Kolab::log('L', "Kolab::LDAP::mapAcls() uid=$uid perm=$perm post=$post", KOLAB_DEBUG);
- if( lc $perm eq 'none' ) { $_ = "$uid none"; }
- elsif( lc $perm eq 'post' ) { $_ = "$uid p"; }
- elsif( lc $perm eq 'read' ) { $_ = "$uid lrs"; }
- elsif( lc $perm eq 'read anon' ) { $_ = "$uid lr"; }
- elsif( lc $perm eq 'read hidden' ) { $_ = "$uid rs"; }
- elsif( lc $perm eq 'append' ) { $_ = "$uid lrsip"; }
- elsif( lc $perm eq 'write' ) { if( $sf ) { $_ = "$uid lrsiwdp"; } else { $_ = "$uid lrsiwcdp"; } }
- elsif( lc $perm eq 'all' ) { if( $sf ) { $_ = "$uid lrsiwdap"; } else { $_ = "$uid lrsiwcdap"; } }
- else { $_ = "$uid $perm"; } # passthrough
- if( $post ) { $_ .= 'p'; }
- Kolab::log('L', "Kolab::LDAP::mapAcls() acl=$_", KOLAB_DEBUG);
- } @$acls;
- if( $sf ) {
- push(@$acls, "manager lrsiwcdap");
- }
- Kolab::log('L', "Kolab::LDAP::mapAcls() acls=".join(", ", @$acls), KOLAB_DEBUG);
- return $acls;
+ Kolab::log('L', "Kolab::LDAP::mapAcls() acls=".join(", ", @$acls), KOLAB_DEBUG);
+ return $acls;
}
sub createObject
@@ -459,7 +461,7 @@ sub createObject
." because it is deleted", KOLAB_DEBUG);
return;
}
- if( ($kolabhomeserver && $kolabhomeserver ne lc($Kolab::config{'fqdnhostname'}))
+ if( ($kolabhomeserver && $kolabhomeserver ne lc($Kolab::config{'fqdnhostname'}))
|| $kolabimapserver && $kolabimapserver ne lc(hostfqdn()) ) {
# We are not on the home server
if( $p eq 'sf' ) {
@@ -593,28 +595,30 @@ sub createObject
}
sub createMasterLDAP {
- my $uri = $Kolab::config{'ldap_master_uri'};
-
- my $masterldap = Net::LDAP->new(
- $uri,
- version => 3,
- timeout => 20,
- verify => 'none',
- onerror => 'undef' );
- if( defined( $masterldap ) ) {
- my $mesg = $masterldap->bind(
- $Kolab::config{'bind_dn'},
- password => $Kolab::config{'bind_pw'});
- if ($mesg->code) {
- Kolab::log('L', "Unable to bind to `$uri', LDAP Error = `"
- .$mesg->error."'", KOLAB_ERROR);
- undef( $masterldap );
+ my $uri = $Kolab::config{'ldap_master_uri'};
+
+ my $masterldap = Net::LDAP->new(
+ $uri,
+ version => 3,
+ timeout => 20,
+ verify => 'none',
+ onerror => 'undef' );
+
+ if( defined( $masterldap ) ) {
+ my $mesg = $masterldap->bind(
+ $Kolab::config{'bind_dn'},
+ password => $Kolab::config{'bind_pw'});
+
+ if ($mesg->code) {
+ Kolab::log('L', "Unable to bind to `$uri', LDAP Error = `"
+ .$mesg->error."'", KOLAB_ERROR);
+ undef( $masterldap );
+ }
+ } else {
+ Kolab::log('L', "Unable to connect to `$uri'"
+ , KOLAB_ERROR);
}
- } else {
- Kolab::log('L', "Unable to connect to `$uri'"
- , KOLAB_ERROR);
- }
- return $masterldap;
+ return $masterldap;
}
sub deleteObject
@@ -623,7 +627,7 @@ sub deleteObject
# deletion, as we nuke the mailbox
#
# The graveyard code will handle the case of an object `going missing'.
-
+
my $ldap = shift;
my $cyrus = shift;
my $object = shift;
@@ -639,83 +643,83 @@ sub deleteObject
if ($remfromldap) {
my $dn = $object->dn;
- my $del = $object->get_value($Kolab::config{$p . '_field_deleted'}, asref => 1);
- my $masterldap;
- if( $Kolab::config{'ldap_master_uri'} eq $Kolab::config{'ldap_uri'} ) {
- # We are already connected to the LDAP master, just go ahead
- $masterldap = $ldap;
- } else {
- $masterldap = createMasterLDAP;
- }
- if( !defined( $masterldap ) ) {
- # Problem here, could not connect to master!
- Kolab::log('L', "Unable to remove DN `$dn', master LDAP server not available", KOLAB_WARN);
- return 0;
- }
- if( lc ($Kolab::config{'is_master'}) eq 'true' && ref($del) eq 'ARRAY' && scalar(@$del) == 1 ) {
- # Ok we are the last one and the master
- if( $Kolab::config{'kolab_remove_objectclass'} ) {
- # Remove the kolab-related objectClasses
- # Some people find it useful to integrate Kolab
- # with an existing LDAP database and when a Kolab
- # object is to be deleted, it should just remove
- # the Kolab stuff and leave the rest of the object
- # in the database.
- #
- # This is what we do here.
- # Warning: All attributes in the kolab-related
- # objectclasses will be deleted!
- #
- # PENDING(steffen): Only remove attributes that _have_ to
- # be removed.
- Kolab::log('L', "Removing Kolab objectClasses from DN `$dn'");
- my $schema = $masterldap->schema( $dn );
- # PENDING(steffen): Dont hardcode objectClasses
- foreach my $c qw(kolabInetOrgPerson kolabGroupOfNames) {
- my @may = map $_->{name}, $schema->may($c);
- my @must = map $_->{name}, $schema->must($c);
- foreach my $attr (@must,@may,split(' ',$Kolab::config{'kolab_remove_attributes'})) {
- # Remove attributes
- Kolab::log('L', "Removing attribute $attr", KOLAB_WARN);
- my $mesg = $masterldap->modify( $dn,
- delete => $attr );
- if ($mesg && $mesg->code ) {
- Kolab::log('L', "Unable to remove attribute $attr from DN `$dn': ".$mesg->error, KOLAB_WARN);
- }
- }
- # Remove objectClass
- my $mesg = $masterldap->modify( $dn,
- delete => { 'objectClass' => $c } );
- if ($mesg && $mesg->code ) {
- Kolab::log('L', "Unable to remove Kolab objectClas $_ from DN `$dn': ".$mesg->error, KOLAB_WARN);
- }
- }
- } else {
- # Default behaviour, delete the object
- Kolab::log('L', "Removing DN `$dn'");
- my $mesg = $masterldap->delete($dn);
- if ($mesg && $mesg->code ) {
- Kolab::log('L', "Unable to remove DN `$dn': ".$mesg->error, KOLAB_WARN);
- }
- }
- } elsif( lc ($Kolab::config{'is_master'}) eq 'false' ) {
- # Just remove us from the kolabdeleteflag
- # master does not perform this step as it should
- # be the last to delete and remove the object
- Kolab::log('L', "Removing ".$Kolab::config{'fqdnhostname'}." from ".
- $Kolab::config{$p . '_field_deleted'}." in `$dn'");
- my $mesg = $masterldap->modify( $dn, delete =>
- { $Kolab::config{$p . '_field_deleted'} =>
- $Kolab::config{'fqdnhostname'} } );
- if ($mesg && $mesg->code) {
- Kolab::log('L', "Unable to remove ".$Kolab::config{'fqdnhostname'}
- ." from kolabdeleteflag in `$dn': ".$mesg->error, KOLAB_WARN);
- }
- }
- if( $ldap != $masterldap ) {
- # Disconnect from master if we are the slave
- $masterldap->disconnect;
- }
+ my $del = $object->get_value($Kolab::config{$p . '_field_deleted'}, asref => 1);
+ my $masterldap;
+ if( $Kolab::config{'ldap_master_uri'} eq $Kolab::config{'ldap_uri'} ) {
+ # We are already connected to the LDAP master, just go ahead
+ $masterldap = $ldap;
+ } else {
+ $masterldap = createMasterLDAP;
+ }
+ if( !defined( $masterldap ) ) {
+ # Problem here, could not connect to master!
+ Kolab::log('L', "Unable to remove DN `$dn', master LDAP server not available", KOLAB_WARN);
+ return 0;
+ }
+ if( lc ($Kolab::config{'is_master'}) eq 'true' && ref($del) eq 'ARRAY' && scalar(@$del) == 1 ) {
+ # Ok we are the last one and the master
+ if( $Kolab::config{'kolab_remove_objectclass'} ) {
+ # Remove the kolab-related objectClasses
+ # Some people find it useful to integrate Kolab
+ # with an existing LDAP database and when a Kolab
+ # object is to be deleted, it should just remove
+ # the Kolab stuff and leave the rest of the object
+ # in the database.
+ #
+ # This is what we do here.
+ # Warning: All attributes in the kolab-related
+ # objectclasses will be deleted!
+ #
+ # PENDING(steffen): Only remove attributes that _have_ to
+ # be removed.
+ Kolab::log('L', "Removing Kolab objectClasses from DN `$dn'");
+ my $schema = $masterldap->schema( $dn );
+ # PENDING(steffen): Dont hardcode objectClasses
+ foreach my $c qw(kolabInetOrgPerson kolabGroupOfNames) {
+ my @may = map $_->{name}, $schema->may($c);
+ my @must = map $_->{name}, $schema->must($c);
+ foreach my $attr (@must,@may,split(' ',$Kolab::config{'kolab_remove_attributes'})) {
+ # Remove attributes
+ Kolab::log('L', "Removing attribute $attr", KOLAB_WARN);
+ my $mesg = $masterldap->modify( $dn,
+ delete => $attr );
+ if ($mesg && $mesg->code ) {
+ Kolab::log('L', "Unable to remove attribute $attr from DN `$dn': ".$mesg->error, KOLAB_WARN);
+ }
+ }
+ # Remove objectClass
+ my $mesg = $masterldap->modify( $dn,
+ delete => { 'objectClass' => $c } );
+ if ($mesg && $mesg->code ) {
+ Kolab::log('L', "Unable to remove Kolab objectClas $_ from DN `$dn': ".$mesg->error, KOLAB_WARN);
+ }
+ }
+ } else {
+ # Default behaviour, delete the object
+ Kolab::log('L', "Removing DN `$dn'");
+ my $mesg = $masterldap->delete($dn);
+ if ($mesg && $mesg->code ) {
+ Kolab::log('L', "Unable to remove DN `$dn': ".$mesg->error, KOLAB_WARN);
+ }
+ }
+ } elsif( lc ($Kolab::config{'is_master'}) eq 'false' ) {
+ # Just remove us from the kolabdeleteflag
+ # master does not perform this step as it should
+ # be the last to delete and remove the object
+ Kolab::log('L', "Removing ".$Kolab::config{'fqdnhostname'}." from ".
+ $Kolab::config{$p . '_field_deleted'}." in `$dn'");
+ my $mesg = $masterldap->modify( $dn, delete =>
+ { $Kolab::config{$p . '_field_deleted'} =>
+ $Kolab::config{'fqdnhostname'} } );
+ if ($mesg && $mesg->code) {
+ Kolab::log('L', "Unable to remove ".$Kolab::config{'fqdnhostname'}
+ ." from kolabdeleteflag in `$dn': ".$mesg->error, KOLAB_WARN);
+ }
+ }
+ if( $ldap != $masterldap ) {
+ # Disconnect from master if we are the slave
+ $masterldap->disconnect;
+ }
}
my $hooksdir = $Kolab::config{'kolab_hooksdir'} . '/delete';
@@ -724,12 +728,12 @@ sub deleteObject
closedir(DIR);
foreach my $hook (@hooks) {
- system($Kolab::config{'kolab_hooksdir'} . '/delete/' . $hook . " $uid");
- if ($?==0) {
- Kolab::log('L', "Successfully ran hook $hook for user $uid.", KOLAB_DEBUG);
- } else {
- Kolab::log('L', "Failed running hook $hook for user $uid.", KOLAB_ERROR);
- }
+ system($Kolab::config{'kolab_hooksdir'} . '/delete/' . $hook . " $uid");
+ if ($?==0) {
+ Kolab::log('L', "Successfully ran hook $hook for user $uid.", KOLAB_DEBUG);
+ } else {
+ Kolab::log('L', "Failed running hook $hook for user $uid.", KOLAB_ERROR);
+ }
}
if (!$uid) {
@@ -755,8 +759,8 @@ sub sync
$group_timestamp = syncBasic($cyrus, 'group', '', $group_timestamp, 0);
if( !$cyrus ) {
- # We could not connect, bail out for now
- return 0;
+ # We could not connect, bail out for now
+ return 0;
}
# Check that all mailboxes correspond to LDAP objects
Kolab::log('L', 'Synchronising mailboxes');
@@ -783,7 +787,7 @@ sub sync
# an error when iterating through the objects (Lost connection, invalid DNs)
foreach $guid (keys %$uid_db) {
if (defined $$uid_db{$guid} && exists $objects{$$uid_db{$guid}}) {
- graveyardStore($guid, $$uid_db{$guid});
+ graveyardStore($guid, $$uid_db{$guid});
}
}
uidcacheClose(%$uid_db);
@@ -792,7 +796,7 @@ sub sync
my $newuid;
foreach $newuid (keys %newuid_db) {
- uidcacheStore($newuid, $newuid_db{$newuid});
+ uidcacheStore($newuid, $newuid_db{$newuid});
}
syncDomains();
@@ -804,26 +808,26 @@ sub sync
# so we have to hack it ourselves
sub parse_generalized_time
{
- my $ts = shift;
- # YYYYMMDDHHMMSSZ
- if( $ts =~ /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z/ ) {
- my $t = 0;
- eval { $t = timegm($6,$5,$4,$3,$2-1,$1); };
- return $t;
- } else {
- return 0;
- }
+ my $ts = shift;
+ # YYYYMMDDHHMMSSZ
+ if( $ts =~ /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)Z/ ) {
+ my $t = 0;
+ eval { $t = timegm($6,$5,$4,$3,$2-1,$1); };
+ return $t;
+ } else {
+ return 0;
+ }
}
# Returns the largest of two string-rep.
# of LDAP generalizedTime
sub max_generalized_time
{
- my $ts1 = shift;
- my $ts2 = shift;
- if( parse_generalized_time($ts1) >
- parse_generalized_time($ts2) ) { return $ts1; }
- else { return $ts2; }
+ my $ts1 = shift;
+ my $ts2 = shift;
+ if( parse_generalized_time($ts1) >
+ parse_generalized_time($ts2) ) { return $ts1; }
+ else { return $ts2; }
}
sub syncBasic
@@ -866,7 +870,7 @@ sub syncBasic
);
if ( UNIVERSAL::isa( $ldapmesg, 'Net::LDAP::Search') && $ldapmesg->code() <= 0) {
- while( $ldapobject = $ldapmesg->pop_entry ) {
+ while( $ldapobject = $ldapmesg->pop_entry ) {
deleteObject($ldap, $cyrus, $ldapobject, 1, $p);
}
} else {
@@ -875,14 +879,15 @@ sub syncBasic
# Now check that all objects in LDAP have corresponding mailboxes
# This also resurrects any missing users, if neccessary
- my $filter;
- if( $ts eq "" ) {
- $filter = '(&(objectClass=' . $Kolab::config{$p . '_object_class'} . ")$add)",
- } else {
- $filter = '(&(objectClass=' . $Kolab::config{$p . '_object_class'} . ")("
- .$Kolab::config{$p.'_field_modified'}.">=$ts)$add)";
- }
- Kolab::log('L', "filter is $filter", KOLAB_DEBUG);
+ my $filter;
+ if( $ts eq "" ) {
+ $filter = '(&(objectClass=' . $Kolab::config{$p . '_object_class'} . ")$add)",
+ } else {
+ $filter = '(&(objectClass=' . $Kolab::config{$p . '_object_class'} . ")("
+ .$Kolab::config{$p.'_field_modified'}.">=$ts)$add)";
+ }
+
+ Kolab::log('L', "filter is $filter", KOLAB_DEBUG);
$ldapmesg = $ldap->search(
base => $dn,
scope => 'sub',
@@ -890,16 +895,16 @@ sub syncBasic
attrs => [
'*',
$Kolab::config{$p . '_field_guid'},
- $Kolab::config{$p . '_field_modified'},
+ $Kolab::config{$p . '_field_modified'},
$Kolab::config{$p . '_field_quota'},
$Kolab::config{$p . '_field_deleted'},
],
);
if ( UNIVERSAL::isa( $ldapmesg, 'Net::LDAP::Search') && $ldapmesg->code() <= 0) {
- while( $ldapobject = $ldapmesg->pop_entry ) {
+ while( $ldapobject = $ldapmesg->pop_entry ) {
createObject($ldap, $cyrus, $ldapobject, 1, $p, $doacls);
- $ts = max_generalized_time($ts,$ldapobject->get_value($Kolab::config{$p . '_field_modified'}));
+ $ts = max_generalized_time($ts,$ldapobject->get_value($Kolab::config{$p . '_field_modified'}));
}
} else {
Kolab::log('L', "Unable to locate `$p' objects in DN `$dn'", KOLAB_WARN);
@@ -937,12 +942,12 @@ sub syncDomains
$ldapmesg = $ldap->search(
base => 'cn=internal,' . $Kolab::config{'base_dn'},
scope => 'one',
- filter => '(&(objectClass=kolabInetOrgPerson)(cn=calendar))',
- attrs => [
- 'objectClass',
- 'uid',
- ],
- );
+ filter => '(&(objectClass=kolabInetOrgPerson)(cn=calendar))',
+ attrs => [
+ 'objectClass',
+ 'uid',
+ ],
+ );
if ( UNIVERSAL::isa( $ldapmesg, 'Net::LDAP::Search') && $ldapmesg->count() > 0) {
Kolab::log('L', "Identified old calendar user with DN `$dn'", KOLAB_DEBUG);
@@ -950,44 +955,44 @@ sub syncDomains
$ldap->moddn($dn, newrdn => $cn, deleteoldrdn => 1);
Kolab::log('L', "Renamed old calendar user with DN `$dn' to DN `$cn'", KOLAB_INFO);
} else {
- Kolab::log('L', "Unable to locate old calendar user with DN `$dn'", KOLAB_DEBUG);
+ Kolab::log('L', "Unable to locate old calendar user with DN `$dn'", KOLAB_DEBUG);
}
if( ref($Kolab::config{'postfix-mydestination'}) eq 'ARRAY' ) {
- @domains = @{$Kolab::config{'postfix-mydestination'}};
+ @domains = @{$Kolab::config{'postfix-mydestination'}};
} else {
- @domains =( $Kolab::config{'postfix-mydestination'} );
+ @domains =( $Kolab::config{'postfix-mydestination'} );
}
my $sha_pw = hash_pw($Kolab::config{'calendar_pw'});
foreach $domain (@domains) {
- $uid = $Kolab::config{'calendar_id'} . '@' . $domain;
- $dn = 'cn=' . $uid . ',cn=internal,' . $Kolab::config{'base_dn'};
- $ldapmesg = $ldap->search(
- base => $dn,
- scope => 'one',
- filter => '(&(objectClass=kolabInetOrgPerson))',
+ $uid = $Kolab::config{'calendar_id'} . '@' . $domain;
+ $dn = 'cn=' . $uid . ',cn=internal,' . $Kolab::config{'base_dn'};
+ $ldapmesg = $ldap->search(
+ base => $dn,
+ scope => 'one',
+ filter => '(&(objectClass=kolabInetOrgPerson))',
attrs => [
'objectClass',
'uid',
- ],
- );
- if ( UNIVERSAL::isa( $ldapmesg, 'Net::LDAP::Search') && $ldapmesg->code() <= 0) {
- Kolab::log('L', "Calendar user for domain `$domain' exists", KOLAB_DEBUG);
- } else {
- $ldapobject = Net::LDAP::Entry->new;
- $ldapobject->replace('cn' => $uid,
- 'sn' => 'n/a n/a',
- 'uid' => $uid,
- 'userPassword' => $sha_pw,
- 'objectclass' => ['top','inetorgperson','kolabinetorgperson']);
- $ldapobject->dn($dn);
- $ldapobject->update($ldap);
- undef $ldapobject;
- Kolab::log('L', "Created new calendar user with DN `$dn' for domain `$domain'", KOLAB_INFO);
- }
- }
+ ],
+ );
+ if ( UNIVERSAL::isa( $ldapmesg, 'Net::LDAP::Search') && $ldapmesg->code() <= 0) {
+ Kolab::log('L', "Calendar user for domain `$domain' exists", KOLAB_DEBUG);
+ } else {
+ $ldapobject = Net::LDAP::Entry->new;
+ $ldapobject->replace('cn' => $uid,
+ 'sn' => 'n/a n/a',
+ 'uid' => $uid,
+ 'userPassword' => $sha_pw,
+ 'objectclass' => ['top','inetorgperson','kolabinetorgperson']);
+ $ldapobject->dn($dn);
+ $ldapobject->update($ldap);
+ undef $ldapobject;
+ Kolab::log('L', "Created new calendar user with DN `$dn' for domain `$domain'", KOLAB_INFO);
+ }
+ }
}
# Taken from Samba::LDAP::User.pm
@@ -1016,7 +1021,6 @@ sub ldap_error {
Kolab::log('L', $errstr, KOLAB_ERROR);
}
-
1;
__END__
# Below is stub documentation for your module. You'd better edit it!
diff --git a/lib/Kolab/LDAP/Backend.pm b/lib/Kolab/LDAP/Backend.pm
index ba1c9d5..ef72171 100644
--- a/lib/Kolab/LDAP/Backend.pm
+++ b/lib/Kolab/LDAP/Backend.pm
@@ -63,10 +63,10 @@ sub load
my $backend;
if (!defined $non_directory) {
- $p .= '_' if ($p);
- $backend = $Kolab::config{$p . 'directory_mode'};
+ $p .= '_' if ($p);
+ $backend = $Kolab::config{$p . 'directory_mode'};
} else {
- $backend = $p;
+ $backend = $p;
}
return if (exists($backends{$backend}));
@@ -105,7 +105,7 @@ sub run
my $func = $run{$backend};
unless (eval '&$func') {
$func = 'Kolab::LDAP::Backend::' . $backend . '::run';
- Kolab::log('B', "Error in function `$func': $@, exiting", KOLAB_ERROR);
+ Kolab::log('B', "Error in function `$func': $@, exiting", KOLAB_ERROR);
exit(1);
}
}
diff --git a/lib/Kolab/LDAP/Backend/ad.pm b/lib/Kolab/LDAP/Backend/ad.pm
index 668b67f..33f0789 100644
--- a/lib/Kolab/LDAP/Backend/ad.pm
+++ b/lib/Kolab/LDAP/Backend/ad.pm
@@ -48,7 +48,7 @@ our %EXPORT_TAGS = (
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
-
+
);
our $VERSION = '0.9';
@@ -80,35 +80,35 @@ sub changeCallback
my $issearch = $mesg->isa("Net::LDAP::Search");
if (!$issearch) {
- Kolab::log('AD', 'mesg is not a search object, testing code...', KOLAB_DEBUG);
- if ($mesg->code == 88) {
- Kolab::log('AD', 'changeCallback() -> Exit code received, returning', KOLAB_DEBUG);
- return;
- } elsif ($mesg->code) {
- Kolab::log('AD', "mesg->code = `" . $mesg->code . "', mesg->msg = `" . $mesg->error . "'", KOLAB_DEBUG);
- &abort;
- }
+ Kolab::log('AD', 'mesg is not a search object, testing code...', KOLAB_DEBUG);
+ if ($mesg->code == 88) {
+ Kolab::log('AD', 'changeCallback() -> Exit code received, returning', KOLAB_DEBUG);
+ return;
+ } elsif ($mesg->code) {
+ Kolab::log('AD', "mesg->code = `" . $mesg->code . "', mesg->msg = `" . $mesg->error . "'", KOLAB_DEBUG);
+ &abort;
+ }
} else {
- Kolab::log('AD', 'mesg is a search object, not testing code', KOLAB_DEBUG);
+ Kolab::log('AD', 'mesg is a search object, not testing code', KOLAB_DEBUG);
}
if (!$entry) {
- Kolab::log('AD', 'changeCallback() called with a null entry', KOLAB_DEBUG);
- return;
+ Kolab::log('AD', 'changeCallback() called with a null entry', KOLAB_DEBUG);
+ return;
} elsif (!$entry->isa("Net::LDAP::Entry")) {
- Kolab::log('AD', 'changeCallback() called with an invalid entry', KOLAB_DEBUG);
- return;
+ Kolab::log('AD', 'changeCallback() called with an invalid entry', KOLAB_DEBUG);
+ return;
}
if (!Kolab::LDAP::isObject($entry, $Kolab::config{'user_object_class'})) {
- Kolab::log('AD', "Entry is not a `" . $Kolab::config{'user_object_class'} . "', returning", KOLAB_DEBUG);
- return;
+ Kolab::log('AD', "Entry is not a `" . $Kolab::config{'user_object_class'} . "', returning", KOLAB_DEBUG);
+ return;
}
my $deleted = $entry->get_value($Kolab::config{'user_field_deleted'}) || 0;
if ($deleted) {
- Kolab::LDAP::deleteObject($ldap, $cyrus, $entry);
- return;
+ Kolab::LDAP::deleteObject($ldap, $cyrus, $entry);
+ return;
}
Kolab::LDAP::createObject($ldap, $cyrus, $entry);
@@ -123,8 +123,8 @@ sub run
$SIG{'TERM'} = \&shutdown;
END {
- alarm 0;
- Kolab::LDAP::destroy($ldap);
+ alarm 0;
+ Kolab::LDAP::destroy($ldap);
}
my $mesg;
@@ -136,81 +136,81 @@ sub run
Kolab::log('AD', 'Cyrus connection established', KOLAB_DEBUG);
while (1) {
- Kolab::log('AD', 'Creating LDAP connection to AD server', KOLAB_DEBUG);
-
- $ldap = Kolab::LDAP::create(
- $Kolab::config{'user_ldap_ip'},
- $Kolab::config{'user_ldap_port'},
- $Kolab::config{'user_bind_dn'},
- $Kolab::config{'user_bind_pw'},
- 1
- );
-
- if (!$ldap) {
- Kolab::log('AD', 'Sleeping 5 seconds...');
- sleep 5;
- next;
- }
-
- Kolab::log('AD', 'LDAP connection established', KOLAB_DEBUG);
-
- Kolab::LDAP::ensureAsync($ldap);
-
- Kolab::log('AD', 'Async checked', KOLAB_DEBUG);
-
- my $ctrl = Net::LDAP::Control->new(
- type => '1.2.840.113556.1.4.528',
- critical => 'true'
- );
+ Kolab::log('AD', 'Creating LDAP connection to AD server', KOLAB_DEBUG);
+
+ $ldap = Kolab::LDAP::create(
+ $Kolab::config{'user_ldap_ip'},
+ $Kolab::config{'user_ldap_port'},
+ $Kolab::config{'user_bind_dn'},
+ $Kolab::config{'user_bind_pw'},
+ 1
+ );
- Kolab::log('AD', 'Control created', KOLAB_DEBUG);
+ if (!$ldap) {
+ Kolab::log('AD', 'Sleeping 5 seconds...');
+ sleep 5;
+ next;
+ }
- my @userdns = split(/;/, $Kolab::config{'user_dn_list'});
- my $userdn;
+ Kolab::log('AD', 'LDAP connection established', KOLAB_DEBUG);
- Kolab::log('AD', 'User DN list = ' . $Kolab::config{'user_dn_list'}, KOLAB_DEBUG);
+ Kolab::LDAP::ensureAsync($ldap);
- if (length(@userdns) == 0) {
- Kolab::log('AD', 'No user DNs specified, exiting', KOLAB_ERROR);
- exit(1);
- }
+ Kolab::log('AD', 'Async checked', KOLAB_DEBUG);
- foreach $userdn (@userdns) {
- Kolab::log('AD', "Registering change notification on DN `$userdn'");
-
- $mesg = $ldap->search (
- base => $userdn,
- scope => 'one',
- control => [ $ctrl ],
- callback => \&changeCallback,
- filter => '(objectClass=*)',
- attrs => [
- '*',
- $Kolab::config{'user_field_guid'},
- $Kolab::config{'user_field_modified'},
- $Kolab::config{'user_field_quota'},
- $Kolab::config{'user_field_deleted'},
- ],
+ my $ctrl = Net::LDAP::Control->new(
+ type => '1.2.840.113556.1.4.528',
+ critical => 'true'
);
- Kolab::log('AD', "Change notification registered on `$userdn'");
- }
-
- eval {
- local $SIG{ALRM} = sub {
- alarm 0;
- Kolab::log('AD', 'Connection refresh period expired; tearing down connection');
-
- Kolab::LDAP::destroy($ldap);
- next;
+ Kolab::log('AD', 'Control created', KOLAB_DEBUG);
+
+ my @userdns = split(/;/, $Kolab::config{'user_dn_list'});
+ my $userdn;
+
+ Kolab::log('AD', 'User DN list = ' . $Kolab::config{'user_dn_list'}, KOLAB_DEBUG);
+
+ if (length(@userdns) == 0) {
+ Kolab::log('AD', 'No user DNs specified, exiting', KOLAB_ERROR);
+ exit(1);
+ }
+
+ foreach $userdn (@userdns) {
+ Kolab::log('AD', "Registering change notification on DN `$userdn'");
+
+ $mesg = $ldap->search (
+ base => $userdn,
+ scope => 'one',
+ control => [ $ctrl ],
+ callback => \&changeCallback,
+ filter => '(objectClass=*)',
+ attrs => [
+ '*',
+ $Kolab::config{'user_field_guid'},
+ $Kolab::config{'user_field_modified'},
+ $Kolab::config{'user_field_quota'},
+ $Kolab::config{'user_field_deleted'},
+ ],
+ );
+
+ Kolab::log('AD', "Change notification registered on `$userdn'");
+ }
+
+ eval {
+ local $SIG{ALRM} = sub {
+ alarm 0;
+ Kolab::log('AD', 'Connection refresh period expired; tearing down connection');
+
+ Kolab::LDAP::destroy($ldap);
+ next;
+ };
+
+ Kolab::log('AD', 'Waiting for changes (refresh period = ' . $Kolab::config{'conn_refresh_period'} . ' minutes)...');
+ alarm $Kolab::config{'conn_refresh_period'} * 60;
+ $mesg->sync;
+ alarm 0;
};
-
- Kolab::log('AD', 'Waiting for changes (refresh period = ' . $Kolab::config{'conn_refresh_period'} . ' minutes)...');
- alarm $Kolab::config{'conn_refresh_period'} * 60;
- $mesg->sync;
- alarm 0;
- };
- }
+ } # End of while
1;
}
diff --git a/lib/Kolab/LDAP/Backend/fds.pm b/lib/Kolab/LDAP/Backend/fds.pm
index 1c5b68a..16044d7 100644
--- a/lib/Kolab/LDAP/Backend/fds.pm
+++ b/lib/Kolab/LDAP/Backend/fds.pm
@@ -35,15 +35,15 @@ our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
'all' => [ qw(
- &startup
- &run
+ &startup
+ &run
) ]
);
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
-
+
);
our $VERSION = '0.1';
@@ -73,36 +73,36 @@ sub changeCallback
my $entry = shift || 0;
my $issearch = $mesg->isa("Net::LDAP::Search");
-
+
Kolab::log('FDS', "issearch=" . $issearch , KOLAB_DEBUG);
if (!$issearch) {
- Kolab::log('FDS', 'mesg is not a search object, testing code...', KOLAB_DEBUG);
- if ($mesg->code == 88) {
- Kolab::log('FDS', 'changeCallback() -> Exit code received, returning', KOLAB_DEBUG);
- return;
- } elsif ($mesg->code) {
- Kolab::log('FDS', "mesg->code = `" . $mesg->code . "', mesg->msg = `" . $mesg->error . "'", KOLAB_DEBUG);
- &abort;
- }
+ Kolab::log('FDS', 'mesg is not a search object, testing code...', KOLAB_DEBUG);
+ if ($mesg->code == 88) {
+ Kolab::log('FDS', 'changeCallback() -> Exit code received, returning', KOLAB_DEBUG);
+ return;
+ } elsif ($mesg->code) {
+ Kolab::log('FDS', "mesg->code = `" . $mesg->code . "', mesg->msg = `" . $mesg->error . "'", KOLAB_DEBUG);
+ &abort;
+ }
} else {
- Kolab::log('FDS', 'mesg is a search object, not testing code', KOLAB_DEBUG);
+ Kolab::log('FDS', 'mesg is a search object, not testing code', KOLAB_DEBUG);
}
Kolab::log('FDS', "entry=" . $entry , KOLAB_DEBUG);
-
+
if (!$entry) {
- Kolab::log('FDS', 'changeCallback() called with a null entry', KOLAB_DEBUG);
- goto FOO;
- return;
+ Kolab::log('FDS', 'changeCallback() called with a null entry', KOLAB_DEBUG);
+ goto FOO;
+ return;
} elsif (!$entry->isa("Net::LDAP::Entry")) {
- Kolab::log('FDS', 'changeCallback() called with an invalid entry', KOLAB_DEBUG);
- return;
+ Kolab::log('FDS', 'changeCallback() called with an invalid entry', KOLAB_DEBUG);
+ return;
}
if (!Kolab::LDAP::isObject($entry, $Kolab::config{'user_object_class'}) &&
!Kolab::LDAP::isObject($entry, 'kolab')) {
- Kolab::log('FDS', "Entry is not a `" . $Kolab::config{'user_object_class'} . "' or kolab configuration object, returning", KOLAB_DEBUG);
- return;
+ Kolab::log('FDS', "Entry is not a `" . $Kolab::config{'user_object_class'} . "' or kolab configuration object, returning", KOLAB_DEBUG);
+ return;
}
FOO:
@@ -122,99 +122,102 @@ FOO:
}
sub run {
- # This should be called from a separate thread, as we set our
- # own interrupt handlers here
+ # This should be called from a separate thread, as we set our
+ # own interrupt handlers here
- $SIG{'INT'} = \&shutdown;
- $SIG{'TERM'} = \&shutdown;
+ $SIG{'INT'} = \&shutdown;
+ $SIG{'TERM'} = \&shutdown;
- END {
- alarm 0;
- Kolab::LDAP::destroy($ldap);
- }
+ END {
+ alarm 0;
+ Kolab::LDAP::destroy($ldap);
+ }
- my $mesg;
+ my $mesg;
- Kolab::log('FDS', 'Listener starting up');
+ Kolab::log('FDS', 'Listener starting up');
- $cyrus = Kolab::Cyrus::create;
+ $cyrus = Kolab::Cyrus::create;
- Kolab::log('FDS', 'Cyrus connection established', KOLAB_DEBUG);
+ Kolab::log('FDS', 'Cyrus connection established', KOLAB_DEBUG);
- while (1) {
- Kolab::log('FDS', 'Creating LDAP connection to FDS server', KOLAB_DEBUG);
+ while (1) {
+ Kolab::log('FDS', 'Creating LDAP connection to FDS server', KOLAB_DEBUG);
- $ldap = Kolab::LDAP::create($Kolab::config{'user_ldap_ip'},
- $Kolab::config{'user_ldap_port'},
- $Kolab::config{'user_bind_dn'},
- $Kolab::config{'user_bind_pw'},
- 1
- );
- if (!$ldap) {
- Kolab::log('FDS', 'Sleeping 5 seconds...');
- sleep 5;
- next;
- }
+ $ldap = Kolab::LDAP::create(
+ $Kolab::config{'user_ldap_ip'},
+ $Kolab::config{'user_ldap_port'},
+ $Kolab::config{'user_bind_dn'},
+ $Kolab::config{'user_bind_pw'},
+ 1
+ );
- Kolab::log('FDS', 'LDAP connection established', KOLAB_DEBUG);
+ if (!$ldap) {
+ Kolab::log('FDS', 'Sleeping 5 seconds...');
+ sleep 5;
+ next;
+ }
- Kolab::LDAP::ensureAsync($ldap);
+ Kolab::log('FDS', 'LDAP connection established', KOLAB_DEBUG);
- Kolab::log('FDS', 'Async checked', KOLAB_DEBUG);
+ Kolab::LDAP::ensureAsync($ldap);
- my $ctrl = Net::LDAP::Control->new(
- # type => '1.2.840.113556.1.4.528',
- type => '2.16.840.1.113730.3.4.3',
- critical => 'true'
- );
+ Kolab::log('FDS', 'Async checked', KOLAB_DEBUG);
- Kolab::log('FDS', 'Control created', KOLAB_DEBUG);
+ my $ctrl = Net::LDAP::Control->new(
+# type => '1.2.840.113556.1.4.528',
+ type => '2.16.840.1.113730.3.4.3',
+ critical => 'true'
+ );
- my @userdns = split(/;/, $Kolab::config{'user_dn_list'});
- my $userdn;
+ Kolab::log('FDS', 'Control created', KOLAB_DEBUG);
- Kolab::log('FDS', 'User DN list = ' . $Kolab::config{'user_dn_list'}, KOLAB_DEBUG);
+ my @userdns = split(/;/, $Kolab::config{'user_dn_list'});
+ my $userdn;
- if (length(@userdns) == 0) {
- Kolab::log('FDS', 'No user DNs specified, exiting', KOLAB_ERROR);
- exit(1);
- }
+ Kolab::log('FDS', 'User DN list = ' . $Kolab::config{'user_dn_list'}, KOLAB_DEBUG);
- foreach $userdn (@userdns) {
- Kolab::log('FDS', "Registering change notification on DN `$userdn'");
-
- $mesg = $ldap->search (base => $userdn,
- scope => 'one',
- control => [ $ctrl ],
- callback => \&changeCallback,
- filter => '(objectClass=*)',
- attrs => [ '*',
- $Kolab::config{'user_field_guid'},
- $Kolab::config{'user_field_modified'},
- $Kolab::config{'user_field_quota'},
- $Kolab::config{'user_field_deleted'},
- ],
- );
-
-# $status = ldap_create_persistentsearch_control($ld,$changetypes,$changesonly,$return_echg_ctrls,$ctrl_iscritical,$ctrlp);
-
- Kolab::log('FDS', "Change notification registered on `$userdn'");
- }
+ if (length(@userdns) == 0) {
+ Kolab::log('FDS', 'No user DNs specified, exiting', KOLAB_ERROR);
+ exit(1);
+ }
- eval {
- local $SIG{ALRM} = sub {
- alarm 0;
- Kolab::log('FDS', 'Connection refresh period expired; tearing down connection');
+ foreach $userdn (@userdns) {
+ Kolab::log('FDS', "Registering change notification on DN `$userdn'");
- Kolab::LDAP::destroy($ldap);
- next;
- };
+ $mesg = $ldap->search (
+ base => $userdn,
+ scope => 'one',
+ control => [ $ctrl ],
+ callback => \&changeCallback,
+ filter => '(objectClass=*)',
+ attrs => [ '*',
+ $Kolab::config{'user_field_guid'},
+ $Kolab::config{'user_field_modified'},
+ $Kolab::config{'user_field_quota'},
+ $Kolab::config{'user_field_deleted'},
+ ],
+ );
- Kolab::log('FDS', 'Waiting for changes (refresh period = ' . $Kolab::config{'conn_refresh_period'} . ' minutes)...');
- alarm $Kolab::config{'conn_refresh_period'} * 60;
- $mesg->sync;
- alarm 0;
- };
+# $status = ldap_create_persistentsearch_control($ld,$changetypes,$changesonly,$return_echg_ctrls,$ctrl_iscritical,$ctrlp);
+
+ Kolab::log('FDS', "Change notification registered on `$userdn'");
+ }
+
+ eval {
+ local $SIG{ALRM} = sub {
+ alarm 0;
+ Kolab::log('FDS', 'Connection refresh period expired; tearing down connection');
+
+ Kolab::LDAP::destroy($ldap);
+ next;
+ };
+
+ Kolab::log('FDS', 'Waiting for changes (refresh period = ' . $Kolab::config{'conn_refresh_period'} . ' minutes)...');
+ alarm $Kolab::config{'conn_refresh_period'} * 60;
+ $mesg->sync;
+ alarm 0;
+ };
}
1;
diff --git a/lib/Kolab/LDAP/Backend/slurpd.pm b/lib/Kolab/LDAP/Backend/slurpd.pm
index 8f7cb7a..26b83bb 100644
--- a/lib/Kolab/LDAP/Backend/slurpd.pm
+++ b/lib/Kolab/LDAP/Backend/slurpd.pm
@@ -44,15 +44,15 @@ our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
'all' => [ qw(
- &startup
- &run
- ) ]
+ &startup
+ &run
+ ) ]
);
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
-
+
);
our $VERSION = '0.9';
@@ -234,37 +234,39 @@ sub run
my $listenport = $Kolab::config{'slurpd_port'};
my $listenaddr = $Kolab::config{'slurpd_addr'} || "127.0.0.1";
- TRYCONNECT:
+
+TRYCONNECT:
Kolab::log('SD', "Opening listen server on $listenaddr:$listenport");
$server = IO::Socket::INET->new(
- LocalPort => $listenport,
- Proto => "tcp",
- ReuseAddr => 1,
- Type => SOCK_STREAM,
- LocalAddr => $listenaddr,
- Listen => 10
- );
+ LocalPort => $listenport,
+ Proto => "tcp",
+ ReuseAddr => 1,
+ Type => SOCK_STREAM,
+ LocalAddr => $listenaddr,
+ Listen => 10
+ );
+
if (!$server) {
Kolab::log('SD', "Unable to open TCP listen server on $listenaddr:$listenport, Error = $@", KOLAB_ERROR);
- sleep 1;
- goto TRYCONNECT;
+ sleep 1;
+ goto TRYCONNECT;
}
Kolab::log('SD', 'Listen server opened, waiting for incoming connections');
while ($conn = $server->accept()) {
- # PENDING: Only accept connections from localhost and
- # hosts listed in the kolabhost attribute
+ # PENDING: Only accept connections from localhost and
+ # hosts listed in the kolabhost attribute
- my($peerport, $peeraddr) = sockaddr_in($conn->peername);
- $peeraddr = inet_ntoa( $peeraddr );
+ my($peerport, $peeraddr) = sockaddr_in($conn->peername);
+ $peeraddr = inet_ntoa( $peeraddr );
Kolab::log('SD', "Incoming connection accepted, peer=$peeraddr");
- if( $Kolab::config{'slurpd_accept_addr'} && $peeraddr ne $Kolab::config{'slurpd_accept_addr'} ) {
- Kolab::log('SD', "Unauthorized connection from $peeraddr, closing connection", KOLAB_WARN);
- $conn->close;
- undef $conn;
- next;
- }
+ if( $Kolab::config{'slurpd_accept_addr'} && $peeraddr ne $Kolab::config{'slurpd_accept_addr'} ) {
+ Kolab::log('SD', "Unauthorized connection from $peeraddr, closing connection", KOLAB_WARN);
+ $conn->close;
+ undef $conn;
+ next;
+ }
my $select = IO::Select->new($conn);
@@ -274,25 +276,25 @@ sub run
my $offset = 0;
if (!($select->can_read(0)) && $changes) {
- Kolab::log('SD', 'Change detected w/ no pending LDAP messages; waiting a second...');
- if( !($select->can_read(1)) ) {
- $changes = 0;
- Kolab::log('SD', 'Change detected w/ no pending LDAP messages; reloading services if needed');
- my $kidpid = fork();
- unless (defined $kidpid) {
- die("can't fork: $!");
- }
- if ($kidpid == 0 ) {
- # child
- Kolab::LDAP::sync;
- exit(0);
- }
- waitpid($kidpid, 0);
- Kolab::log('SD', "Running $Kolab::config{'kolabconf_script'}");
- system($Kolab::config{'kolabconf_script'}) == 0
- or Kolab::log('SD', "Failed to run $Kolab::config{'kolabconf_script'}: $?", KOLAB_ERROR);
- Kolab::log('SD', "$Kolab::config{'kolabconf_script'} complete");
- }
+ Kolab::log('SD', 'Change detected w/ no pending LDAP messages; waiting a second...');
+ if( !($select->can_read(1)) ) {
+ $changes = 0;
+ Kolab::log('SD', 'Change detected w/ no pending LDAP messages; reloading services if needed');
+ my $kidpid = fork();
+ unless (defined $kidpid) {
+ die("can't fork: $!");
+ }
+ if ($kidpid == 0 ) {
+ # child
+ Kolab::LDAP::sync;
+ exit(0);
+ }
+ waitpid($kidpid, 0);
+ Kolab::log('SD', "Running $Kolab::config{'kolabconf_script'}");
+ system($Kolab::config{'kolabconf_script'}) == 0
+ or Kolab::log('SD', "Failed to run $Kolab::config{'kolabconf_script'}: $?", KOLAB_ERROR);
+ Kolab::log('SD', "$Kolab::config{'kolabconf_script'} complete");
+ }
}
Kolab::log('SD', 'Waiting for LDAP updates');
@@ -300,12 +302,12 @@ sub run
for ($ready = 1; $conn && $ready; $ready = $select->can_read(0)) {
Kolab::log('SD', 'Reading ASN', KOLAB_DEBUG);
my $newoffset = asn_read($conn, $pdu, $offset);
- if( !$conn->connected() or $offset == $newoffset ) {
- Kolab::log('SD', 'Connection closed', KOLAB_DEBUG);
- $conn->close;
- undef $conn;
- }
- $offset = $newoffset;
+ if( !$conn->connected() or $offset == $newoffset ) {
+ Kolab::log('SD', 'Connection closed', KOLAB_DEBUG);
+ $conn->close;
+ undef $conn;
+ }
+ $offset = $newoffset;
defined($offset) or $offset = 0;
}
@@ -313,29 +315,29 @@ sub run
$request = $LDAPRequest->decode($pdu);
if (!$request) {
Kolab::log('SD', "Unable to decode slurpd request, Error = `" . $LDAPRequest->error . "'", KOLAB_ERROR);
- $conn->close if $conn;
- undef $conn;
- undef $pdu;
+ $conn->close if $conn;
+ undef $conn;
+ undef $pdu;
} else {
- $_ = getRequestType($request);
- Kolab::log('SD', "Request $_ received", KOLAB_DEBUG);
- undef $pdu;
-
- SWITCH: {
- if (/^bindRequest/) { $pdu = responseBind($request); last SWITCH; }
- if (/addRequest/) { $pdu = responseAdd($request); $changes = 1; last SWITCH; }
- if (/delRequest/) { $pdu = responseDel($request); $changes = 1; last SWITCH; }
- if (/modifyRequest/) { $pdu = responseMod($request); $changes = 1; last SWITCH; }
- if (/modDNRequest/) { $pdu = responseModDN($request); $changes = 1; last SWITCH; }
-
- if( $conn ) {
- Kolab::log('SD', 'Unknown request, connection closed', KOLAB_DEBUG);
- $conn->close;
- undef $conn;
- }
- }
- }
- }
+ $_ = getRequestType($request);
+ Kolab::log('SD', "Request $_ received", KOLAB_DEBUG);
+ undef $pdu;
+
+ SWITCH: {
+ if (/^bindRequest/) { $pdu = responseBind($request); last SWITCH; }
+ if (/addRequest/) { $pdu = responseAdd($request); $changes = 1; last SWITCH; }
+ if (/delRequest/) { $pdu = responseDel($request); $changes = 1; last SWITCH; }
+ if (/modifyRequest/) { $pdu = responseMod($request); $changes = 1; last SWITCH; }
+ if (/modDNRequest/) { $pdu = responseModDN($request); $changes = 1; last SWITCH; }
+
+ if( $conn ) {
+ Kolab::log('SD', 'Unknown request, connection closed', KOLAB_DEBUG);
+ $conn->close;
+ undef $conn;
+ }
+ }
+ }
+ }
if ($pdu) {
Kolab::log('SD', 'Writing response', KOLAB_DEBUG);
@@ -343,8 +345,8 @@ sub run
$response = $LDAPResponse->decode($pdu);
if (!$response) {
Kolab::log('SD', "Unable to decode slurpd request, Error = `" . $LDAPRequest->error . "'");
- $conn->close;
- undef $conn;
+ $conn->close;
+ undef $conn;
}
}
}
diff --git a/lib/Kolab/LDAP/Backend/syncrepl.pm b/lib/Kolab/LDAP/Backend/syncrepl.pm
index b4d1e27..5283262 100644
--- a/lib/Kolab/LDAP/Backend/syncrepl.pm
+++ b/lib/Kolab/LDAP/Backend/syncrepl.pm
@@ -22,9 +22,9 @@ use warnings;
use Kolab;
use Kolab::LDAP;
use Net::LDAP qw(
- LDAP_USER_CANCELED
- LDAP_SYNC_REFRESH_ONLY
- LDAP_SYNC_REFRESH_AND_PERSIST
+ LDAP_USER_CANCELED
+ LDAP_SYNC_REFRESH_ONLY
+ LDAP_SYNC_REFRESH_AND_PERSIST
);
use Net::LDAP::Control;
use Net::LDAP::Control::SyncRequest;
@@ -38,64 +38,65 @@ our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
'all' => [ qw(
- &startup
- &run
- ) ]
+ &startup
+ &run
+ ) ]
);
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
-
+
);
our $VERSION = '0.3';
-sub mode {
- LDAP_SYNC_REFRESH_ONLY;
- #LDAP_SYNC_REFRESH_AND_PERSIST;
+sub mode {
+ LDAP_SYNC_REFRESH_ONLY;
+# LDAP_SYNC_REFRESH_AND_PERSIST;
}
# calling without args means: get,
# giving an argument means: set
sub cookie {
- my($cookie) = @_;
- my $syncrepl_cookie_file = $Kolab::config{'syncrepl_cookie_file'} || '/tmp/kolab_syncrepl_cookie_file';
- if(defined($cookie)) {
- if(!open(COOKIE_FILE, '>', $syncrepl_cookie_file)) {
- Kolab::log("SYNCREPL', 'Cannot open file `".$syncrepl_cookie_file.
- "' for writing: $!", KOLAB_DEBUG);
- &abort;
- }
- Kolab::log("SYNCREPL', 'Writing cookie to file: ".$cookie, KOLAB_DEBUG);
- print COOKIE_FILE $cookie;
- close(COOKIE_FILE);
- return $cookie;
- } else {
- #create if it doesn't exists
- if(! -f $syncrepl_cookie_file) {
- open COOKIE_FILE, '>', $syncrepl_cookie_file;
+ my($cookie) = @_;
+ my $syncrepl_cookie_file = $Kolab::config{'syncrepl_cookie_file'} || '/tmp/kolab_syncrepl_cookie_file';
+ if(defined($cookie)) {
+ if(!open(COOKIE_FILE, '>', $syncrepl_cookie_file)) {
+ Kolab::log("SYNCREPL', 'Cannot open file `".$syncrepl_cookie_file.
+ "' for writing: $!", KOLAB_DEBUG);
+ &abort;
+ }
+
+ Kolab::log("SYNCREPL', 'Writing cookie to file: ".$cookie, KOLAB_DEBUG);
+ print COOKIE_FILE $cookie;
+ close(COOKIE_FILE);
+ return $cookie;
+ } else {
+ #create if it doesn't exists
+ if(! -f $syncrepl_cookie_file) {
+ open COOKIE_FILE, '>', $syncrepl_cookie_file;
+ close COOKIE_FILE;
+ }
+ if(!open(COOKIE_FILE, '+<', $syncrepl_cookie_file)) {
+ Kolab::log("SYNCREPL', 'Cannot open file `".$syncrepl_cookie_file.
+ "' for reading: $!", KOLAB_DEBUG);
+ &abort;
+ }
+ read COOKIE_FILE, $cookie, 1024, 0;
close COOKIE_FILE;
+ #an empty file means no cookie:
+ $cookie = undef if !$cookie;
+ return $cookie;
}
- if(!open(COOKIE_FILE, '+<', $syncrepl_cookie_file)) {
- Kolab::log("SYNCREPL', 'Cannot open file `".$syncrepl_cookie_file.
- "' for reading: $!", KOLAB_DEBUG);
- &abort;
- }
- read COOKIE_FILE, $cookie, 1024, 0;
- close COOKIE_FILE;
- #an empty file means no cookie:
- $cookie = undef if !$cookie;
- return $cookie;
- }
}
sub startup { 1; }
sub shutdown
{
- Kolab::log('SYNCREPL', 'Shutting down');
- exit(0);
+ Kolab::log('SYNCREPL', 'Shutting down');
+ exit(0);
}
sub abort
@@ -105,178 +106,201 @@ sub abort
}
sub run {
- # This should be called from a separate thread, as we set our
- # own interrupt handlers here
-
- $SIG{'INT'} = \&shutdown;
- $SIG{'TERM'} = \&shutdown;
-
- END {
- alarm 0;
- Kolab::LDAP::destroy($ldap);
- }
- my $mesg;
-
- while (1) {
- Kolab::log('SYNCREPL', 'Creating LDAP connection to LDAP server', KOLAB_DEBUG);
-
- $ldap = Kolab::LDAP::create($Kolab::config{'user_ldap_ip'},
- $Kolab::config{'user_ldap_port'},
- $Kolab::config{'user_bind_dn'},
- $Kolab::config{'user_bind_pw'},
- 1
- );
- if (!$ldap) {
- Kolab::log('SYNCREPL', 'Sleeping 5 seconds...');
- sleep 5;
- next;
+ # This should be called from a separate thread, as we set our
+ # own interrupt handlers here
+
+ $SIG{'INT'} = \&shutdown;
+ $SIG{'TERM'} = \&shutdown;
+
+ END {
+ alarm 0;
+ Kolab::LDAP::destroy($ldap);
}
- $disconnected = 0;
-
- Kolab::log('SYNCREPL', 'LDAP connection established', KOLAB_DEBUG);
-
- Kolab::LDAP::ensureAsync($ldap);
- Kolab::log('SYNCREPL', 'Async checked', KOLAB_DEBUG);
-
- while($ldap and not $disconnected) {
- my $ctrl = Net::LDAP::Control::SyncRequest->new(
- mode => Kolab::LDAP::Backend::syncrepl::mode(),
- cookie => Kolab::LDAP::Backend::syncrepl::cookie(),
- reloadHint => 0);
- Kolab::log('SYNCREPL', 'Control created: mode='.$ctrl->mode().
- '; cookie='.$ctrl->cookie().
- '; reloadHint='.$ctrl->reloadHint(), KOLAB_DEBUG);
-
- #search
- my $mesg = $ldap->search(base => $Kolab::config{'base_dn'},
- scope => 'sub',
- control => [ $ctrl ],
- callback => \&searchCallback, # call for each entry
- filter => "(objectClass=*)",
- attrs => [ '*',
- $Kolab::config{'user_field_guid'},
- $Kolab::config{'user_field_modified'},
- $Kolab::config{'user_field_quota'},
- $Kolab::config{'user_field_deleted'},
- ],
- );
- Kolab::log('SYNCREPL', 'Search created', KOLAB_DEBUG);
- $mesg->sync;
- Kolab::log('SYNCREPL', "Finished Net::LDAP::Search::sync sleeping 10s", KOLAB_DEBUG);
- sleep 10;
+ my $mesg;
+
+ while (1) {
+ Kolab::log('SYNCREPL', 'Creating LDAP connection to LDAP server', KOLAB_DEBUG);
+
+ $ldap = Kolab::LDAP::create(
+ $Kolab::config{'user_ldap_ip'},
+ $Kolab::config{'user_ldap_port'},
+ $Kolab::config{'user_bind_dn'},
+ $Kolab::config{'user_bind_pw'},
+ 1
+ );
+
+ if (!$ldap) {
+ Kolab::log('SYNCREPL', 'Sleeping 5 seconds...');
+ sleep 5;
+ next;
+ }
+
+ $disconnected = 0;
+
+ Kolab::log('SYNCREPL', 'LDAP connection established', KOLAB_DEBUG);
+
+ Kolab::LDAP::ensureAsync($ldap);
+ Kolab::log('SYNCREPL', 'Async checked', KOLAB_DEBUG);
+
+ while($ldap and not $disconnected) {
+ my $ctrl = Net::LDAP::Control::SyncRequest->new(
+ mode => Kolab::LDAP::Backend::syncrepl::mode(),
+ cookie => Kolab::LDAP::Backend::syncrepl::cookie(),
+ reloadHint => 0
+ );
+
+ Kolab::log('SYNCREPL', 'Control created: mode='.$ctrl->mode().
+ '; cookie='.$ctrl->cookie().
+ '; reloadHint='.$ctrl->reloadHint(), KOLAB_DEBUG);
+
+ #search
+ my $mesg = $ldap->search(
+ base => $Kolab::config{'base_dn'},
+ scope => 'sub',
+ control => [ $ctrl ],
+ callback => \&searchCallback, # call for each entry
+ filter => "(objectClass=*)",
+ attrs => [
+ '*',
+ $Kolab::config{'user_field_guid'},
+ $Kolab::config{'user_field_modified'},
+ $Kolab::config{'user_field_quota'},
+ $Kolab::config{'user_field_deleted'},
+ ],
+ );
+
+ Kolab::log('SYNCREPL', 'Search created', KOLAB_DEBUG);
+ $mesg->sync;
+ Kolab::log('SYNCREPL', "Finished Net::LDAP::Search::sync sleeping 10s", KOLAB_DEBUG);
+ sleep 10;
+ }
}
- }
- 1;
+ 1;
}
#search callback
sub searchCallback {
- my $mesg = shift;
- my $param2 = shift; # might be entry or intermediate
- my @controls = $mesg->control;
- my @sync_controls = ();
- if($param2 && $param2->isa("Net::LDAP::Entry")) {
- Kolab::log('SYNCREPL', 'Received Search Entry', KOLAB_DEBUG);
- #retrieve Sync State Control
- foreach my $ctrl (@controls) {
- push(@sync_controls, $ctrl)
- if $ctrl->isa('Net::LDAP::Control::SyncState');
- }
- if(@sync_controls>1) {
- Kolab::log('SYNCREPL', 'Got search entry with multiple Sync State controls',
- KOLAB_DEBUG);
- return;
- }
- if(!@sync_controls) {
- Kolab::log('SYNCREPL', 'Got search entry without Sync State control',
- KOLAB_DEBUG);
- return;
- }
- if(!$sync_controls[0]->entryUUID) {
- Kolab::log('SYNCREPL', 'Got empty entryUUID', KOLAB_DEBUG);
- return;
- }
- Kolab::log('SYNCREPL', 'Search Entry has Sync State Control: '.
- 'state='.$sync_controls[0]->state().
- '; entryUUID='.unpack("H*",$sync_controls[0]->entryUUID()).
- '; cookie='.(defined($sync_controls[0]->cookie()) ? $sync_controls[0]->cookie() : 'UNDEF')
- , KOLAB_DEBUG);
- if(defined($sync_controls[0]->cookie)) {
- Kolab::LDAP::Backend::syncrepl::cookie($sync_controls[0]->cookie);
- Kolab::log('SYNCREPL',"New cookie: ".Kolab::LDAP::Backend::syncrepl::cookie(),
- KOLAB_DEBUG);
- }
- Kolab::log('SYNCREPL', "Entry (".$param2->changetype."): ".$param2->dn(), KOLAB_DEBUG);
- } elsif($param2 && $param2->isa("Net::LDAP::Reference")) {
- Kolab::log('SYNCREPL', 'Received Search Reference', KOLAB_DEBUG);
- return;
- #if it not first control?
- } elsif($controls[0] and $controls[0]->isa('Net::LDAP::Control::SyncDone')) {
- Kolab::log('SYNCREPL', 'Received Sync Done Control: '.
- 'cookie='.(defined($controls[0]->cookie()) ? $controls[0]->cookie() : 'UNDEF').
- '; refreshDeletes='.$controls[0]->refreshDeletes(), KOLAB_DEBUG);
- #we have a new cookie
- if(defined($controls[0]->cookie())
- and not $controls[0]->cookie() eq ''
- and not $controls[0]->cookie() eq Kolab::LDAP::Backend::syncrepl::cookie()) {
- Kolab::LDAP::Backend::syncrepl::cookie($controls[0]->cookie());
- Kolab::log('SYNCREPL', "New cookie: ".
- Kolab::LDAP::Backend::syncrepl::cookie(), KOLAB_DEBUG);
- Kolab::log('SYNCREPL', "Calling Kolab::LDAP::sync", KOLAB_DEBUG);
- Kolab::LDAP::sync;
- system($Kolab::config{'kolabconf_script'}) == 0
- || Kolab::log('SD', "Failed to run kolabconf: $?", KOLAB_ERROR);
- Kolab::log('SYNCREPL', "Finished Kolab::LDAP::sync sleeping 1s", KOLAB_DEBUG);
- sleep 1; # we get too many bogus change notifications!
- }
- } elsif($param2 && $param2->isa("Net::LDAP::Intermediate")) {
- Kolab::log('SYNCREPL', 'Received Intermediate Message', KOLAB_DEBUG);
- my $attrs = $param2->{asn};
- if($attrs->{newcookie}) {
- Kolab::LDAP::Backend::syncrepl::cookie($attrs->{newcookie});
- Kolab::log('SYNCREPL', "New cookie: ".
- Kolab::LDAP::Backend::syncrepl::cookie(), KOLAB_DEBUG);
- } elsif(my $refreshInfos = ($attrs->{refreshDelete} || $attrs->{refreshPresent})) {
- Kolab::LDAP::Backend::syncrepl::cookie($refreshInfos->{cookie})
- if defined($refreshInfos->{cookie});
- Kolab::log('SYNCREPL',
- (defined($refreshInfos->{cookie}) ? 'New ' : 'Empty ').
- "cookie from ".
- ($attrs->{refreshDelete} ? 'refreshDelete' : 'refreshPresent').
- " (refreshDone=".$refreshInfos->{refreshDone}."): ".
- Kolab::LDAP::Backend::syncrepl::cookie(), KOLAB_DEBUG);
- } elsif(my $syncIdSetInfos = $attrs->{syncIdSet}) {
- Kolab::LDAP::Backend::syncrepl::cookie($syncIdSetInfos->{cookie})
- if defined($syncIdSetInfos->{cookie});
- Kolab::log('SYNCREPL',
- (defined($syncIdSetInfos->{cookie}) ? 'Empty ' : 'New ').
- "cookie from syncIdSet".
- " (refreshDeletes=".$syncIdSetInfos->{refreshDeletes}."): ".
- Kolab::LDAP::Backend::syncrepl::cookie(), KOLAB_DEBUG);
- foreach my $syncUUID ($syncIdSetInfos->{syncUUIDs}) {
- Kolab::log('SYNCREPL', 'entryUUID='.
- unpack("H*",$syncUUID), KOLAB_DEBUG);
- }
- }
- } elsif($mesg->code) {
- if ($mesg->code == 1) {
- Kolab::log('SYNCREPL', 'Communication Error: disconnecting', KOLAB_DEBUG);
- $disconnected = 1;
- return 0;
- } elsif ($mesg->code == LDAP_USER_CANCELED) {
- Kolab::log('SYNCREPL', 'searchCallback() -> Exit code received, returning', KOLAB_DEBUG);
+ my $mesg = shift;
+ my $param2 = shift; # might be entry or intermediate
+ my @controls = $mesg->control;
+ my @sync_controls = ();
+ if($param2 && $param2->isa("Net::LDAP::Entry")) {
+ Kolab::log('SYNCREPL', 'Received Search Entry', KOLAB_DEBUG);
+
+ #retrieve Sync State Control
+ foreach my $ctrl (@controls) {
+ push(@sync_controls, $ctrl)
+ if $ctrl->isa('Net::LDAP::Control::SyncState');
+ }
+
+ if(@sync_controls>1) {
+ Kolab::log('SYNCREPL', 'Got search entry with multiple Sync State controls',
+ KOLAB_DEBUG);
+ return;
+ }
+
+ if(!@sync_controls) {
+ Kolab::log('SYNCREPL', 'Got search entry without Sync State control',
+ KOLAB_DEBUG);
+ return;
+ }
+
+ if(!$sync_controls[0]->entryUUID) {
+ Kolab::log('SYNCREPL', 'Got empty entryUUID', KOLAB_DEBUG);
+ return;
+ }
+
+ Kolab::log('SYNCREPL', 'Search Entry has Sync State Control: '.
+ 'state='.$sync_controls[0]->state().
+ '; entryUUID='.unpack("H*",$sync_controls[0]->entryUUID()).
+ '; cookie='.(defined($sync_controls[0]->cookie()) ? $sync_controls[0]->cookie() : 'UNDEF')
+ , KOLAB_DEBUG);
+
+ if(defined($sync_controls[0]->cookie)) {
+ Kolab::LDAP::Backend::syncrepl::cookie($sync_controls[0]->cookie);
+ Kolab::log('SYNCREPL',"New cookie: ".Kolab::LDAP::Backend::syncrepl::cookie(),
+ KOLAB_DEBUG);
+ }
+
+ Kolab::log('SYNCREPL', "Entry (".$param2->changetype."): ".$param2->dn(), KOLAB_DEBUG);
+ } elsif($param2 && $param2->isa("Net::LDAP::Reference")) {
+ Kolab::log('SYNCREPL', 'Received Search Reference', KOLAB_DEBUG);
return;
- } elsif ($mesg->code == 4096) {
- Kolab::log('SYNCREPL', 'Refresh required', KOLAB_DEBUG);
- Kolab::LDAP::Backend::syncrepl::cookie('');
+ #if it not first control?
+ } elsif($controls[0] and $controls[0]->isa('Net::LDAP::Control::SyncDone')) {
+ Kolab::log('SYNCREPL', 'Received Sync Done Control: '.
+ 'cookie='.(defined($controls[0]->cookie()) ? $controls[0]->cookie() : 'UNDEF').
+ '; refreshDeletes='.$controls[0]->refreshDeletes(), KOLAB_DEBUG);
+
+ #we have a new cookie
+ if(defined($controls[0]->cookie())
+ and not $controls[0]->cookie() eq ''
+ and not $controls[0]->cookie() eq Kolab::LDAP::Backend::syncrepl::cookie()) {
+
+ Kolab::LDAP::Backend::syncrepl::cookie($controls[0]->cookie());
+ Kolab::log('SYNCREPL', "New cookie: ".
+ Kolab::LDAP::Backend::syncrepl::cookie(), KOLAB_DEBUG);
+
+ Kolab::log('SYNCREPL', "Calling Kolab::LDAP::sync", KOLAB_DEBUG);
+ Kolab::LDAP::sync;
+ system($Kolab::config{'kolabconf_script'}) == 0
+ || Kolab::log('SD', "Failed to run kolabconf: $?", KOLAB_ERROR);
+
+ Kolab::log('SYNCREPL', "Finished Kolab::LDAP::sync sleeping 1s", KOLAB_DEBUG);
+ sleep 1; # we get too many bogus change notifications!
+ }
+ } elsif($param2 && $param2->isa("Net::LDAP::Intermediate")) {
+ Kolab::log('SYNCREPL', 'Received Intermediate Message', KOLAB_DEBUG);
+ my $attrs = $param2->{asn};
+ if($attrs->{newcookie}) {
+ Kolab::LDAP::Backend::syncrepl::cookie($attrs->{newcookie});
+ Kolab::log('SYNCREPL', "New cookie: ".
+ Kolab::LDAP::Backend::syncrepl::cookie(), KOLAB_DEBUG);
+
+ } elsif(my $refreshInfos = ($attrs->{refreshDelete} || $attrs->{refreshPresent})) {
+ Kolab::LDAP::Backend::syncrepl::cookie($refreshInfos->{cookie})
+ if defined($refreshInfos->{cookie});
+
+ Kolab::log('SYNCREPL',
+ (defined($refreshInfos->{cookie}) ? 'New ' : 'Empty ').
+ "cookie from ".
+ ($attrs->{refreshDelete} ? 'refreshDelete' : 'refreshPresent').
+ " (refreshDone=".$refreshInfos->{refreshDone}."): ".
+ Kolab::LDAP::Backend::syncrepl::cookie(), KOLAB_DEBUG);
+ } elsif(my $syncIdSetInfos = $attrs->{syncIdSet}) {
+ Kolab::LDAP::Backend::syncrepl::cookie($syncIdSetInfos->{cookie})
+ if defined($syncIdSetInfos->{cookie});
+
+ Kolab::log('SYNCREPL',
+ (defined($syncIdSetInfos->{cookie}) ? 'Empty ' : 'New ').
+ "cookie from syncIdSet".
+ " (refreshDeletes=".$syncIdSetInfos->{refreshDeletes}."): ".
+ Kolab::LDAP::Backend::syncrepl::cookie(), KOLAB_DEBUG);
+
+ foreach my $syncUUID ($syncIdSetInfos->{syncUUIDs}) {
+ Kolab::log('SYNCREPL', 'entryUUID='.
+ unpack("H*",$syncUUID), KOLAB_DEBUG);
+ }
+ }
+ } elsif($mesg->code) {
+ if ($mesg->code == 1) {
+ Kolab::log('SYNCREPL', 'Communication Error: disconnecting', KOLAB_DEBUG);
+ $disconnected = 1;
+ return 0;
+ } elsif ($mesg->code == LDAP_USER_CANCELED) {
+ Kolab::log('SYNCREPL', 'searchCallback() -> Exit code received, returning', KOLAB_DEBUG);
+ return;
+ } elsif ($mesg->code == 4096) {
+ Kolab::log('SYNCREPL', 'Refresh required', KOLAB_DEBUG);
+ Kolab::LDAP::Backend::syncrepl::cookie('');
+ } else {
+ Kolab::log('SYNCREPL', "searchCallback: mesg->code = `" . $mesg->code . "', mesg->msg = `" . $mesg->error . "'", KOLAB_DEBUG);
+ &abort;
+ }
} else {
- Kolab::log('SYNCREPL', "searchCallback: mesg->code = `" . $mesg->code . "', mesg->msg = `" . $mesg->error . "'", KOLAB_DEBUG);
- &abort;
- }
- } else {
- Kolab::log('SYNCREPL', 'Received something else', KOLAB_DEBUG);
- }
- return 0;
+ Kolab::log('SYNCREPL', 'Received something else', KOLAB_DEBUG);
+ }
+ return 0;
}
1;
diff --git a/lib/Kolab/Util.pm b/lib/Kolab/Util.pm
index f115eeb..85612eb 100644
--- a/lib/Kolab/Util.pm
+++ b/lib/Kolab/Util.pm
@@ -99,9 +99,9 @@ sub readConfig
$sep = '\s' if ($sep eq ' ' || $sep eq '#');
my $fd;
- if (!($fd = IO::File->new($file, 'r'))) {
- superLog( "Warning: Could not read $file");
- return %cfg;
+ if (!($fd = IO::File->new($file, 'r'))) {
+ superLog( "Warning: Could not read $file");
+ return %cfg;
}
foreach (<$fd>) {