summaryrefslogtreecommitdiff
path: root/lib/Kolab/LDAP
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Kolab/LDAP')
-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
5 files changed, 490 insertions, 461 deletions
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;