无法使用内容同步操作 (syncrepl) 从 OpenLDAP 服务器获取已删除的项目
Can't get deleted items from OpenLDAP Server using Content Synchronization Operation (syncrepl)
我在 Ubuntu 19.04 VM 上设置了我的 OpenLDAP 服务器并允许复制(使用本教程:https://help.ubuntu.com/lts/serverguide/openldap-server.html#openldap-server-replication)。复制的一切似乎都没问题。
我没有设置消费者服务器,因为我的代码将充当一个消费者服务器,定期拉取修改后的元素。
modified/added 条目已正确检索,但我想获取已删除的项目,但我似乎无法让它工作。
如 RFC https://www.rfc-editor.org/rfc/rfc4533#section-3.3.2 所述,我应该收到一条包含名为“syncUUIDs”的属性的同步信息消息
syncUUIDs contain a set of UUIDs of the entries and references that have been deleted from the content since the last Sync Operation
我的同步请求控件初始化
syncRequestValue = BerConverter.Encode("{iob}", new object[] { refreshOnly, cookieSrc, true });
testdsrc = new DirectoryControl("1.3.6.1.4.1.4203.1.9.1.1", syncRequestValue, true, true);
将控件添加到请求中,然后发送。
request.Controls.Add(testdsrc);
connection.SendRequest(request);
response = (SearchResponse)connection.SendRequest(request);
获取条目,这里我删除了1个条目,修改了1个并添加了1个,我只得到了2个条目(added/modified个)
entries = response.Entries;
if (response.Entries.Count > 0)
{
object[] controlvalue = BerConverter.Decode("{Ob}",
response.Controls[0].GetValue());
cookieSrc = (byte[])controlvalue[0];
var refreshDeletes = (bool)controlvalue[1];
File.WriteAllBytes(strFileName, cookieSrc);
}
你知道它是来自我的 LDAP 服务器的配置还是我的 C# 代码?
不知道是不是:
- 我的服务器发送了正确的响应,但 SearchResponse class 不知道如何解释它
或
- 如果我的服务器配置错误并且根本不发送已删除条目的列表...
通过在我的 OpenLdap 服务器上添加 "sync" 日志级别,我能够看到发送了具有正确 OID 的中间消息。
slapd debug conn=1131 fd=15 ACCEPT from IP=x.x.x.x (IP=0.0.0.0:389)
slapd debug conn=1131 op=0 BIND dn="cn=admin,dc=example,dc=com" method=128
slapd debug conn=1131 op=0 BIND dn="cn=admin,dc=example,dc=com" mech=SIMPLE ssf=0
slapd debug conn=1131 op=0 RESULT tag=97 err=0 text=
slapd debug conn=1131 op=1 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)"
slapd debug conn=1131 op=1 SRCH attr=dn objectClass cn displayName
**slapd debug conn=1131 op=1 INTERM oid=1.3.6.1.4.1.4203.1.9.1.4**
slapd debug conn=1131 op=1 ENTRY dn="ou=uni,dc=example,dc=com"
slapd debug syncprov_search_response: cookie=rid=000,csn=20190924091959.141380Z#000000#000#000000
slapd debug conn=1131 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
slapd debug conn=1131 op=2 UNBIND
slapd debug conn=1131 fd=15 closed
通过使用 Perl 脚本和 Perl Net::LDAP 库,我能够看到响应值包含已删除条目的 UUIDS。
我现在知道我的服务器已正确配置,但我不知道如何使用 .NET 获取 UUID
use Net::LDAP;
use Net::LDAP::Control::SyncRequest;
use Net::LDAP::Intermediate::SyncInfo;
use Net::LDAP::Constant qw(
LDAP_SYNC_REFRESH_ONLY
LDAP_SYNC_REFRESH_AND_PERSIST
LDAP_SUCCESS );
use Data::Dumper qw(Dumper);
$ldap = Net::LDAP->new( "127.0.0.1:389" ) or die($@);
$req = Net::LDAP::Control::SyncRequest->new( mode => LDAP_SYNC_REFRESH_ONLY, cookie => "rid=000,csn=20190912114502.963050Z#000000#000#000000" );
my $mesg = $ldap->search(base=> 'dc=example,dc=com',
scope => 'sub',
control => [ $req ],
callback => \&searchCallback, # call for each entry
filter => "(objectClass=*)",
attrs => [ '*']);
print "\n==========\n";
print Dumper($mesg);
sub searchCallback {
my $message = shift;
my $entry = shift;
my @controls = $message->control;
print Dumper($message);
print "\n==========\n";
my $count = scalar(@controls);
print " $count controls in response\n";
if ( $count == 0 ) {
if ($message->isa('Net::LDAP::Intermediate::SyncInfo')) {
print "Received Sync Info message\n";
}
return;
}
if (!defined($controls[0]) ) {
print " control 0 is undefined\n";
return;
}
if ($controls[0]->isa('Net::LDAP::Control::SyncState')) {
print "Received Sync State Control\n";
print $entry->dn()."\n";
#print Dumper($controls[0]->entryUUID);
print 'State: '.$controls[0]->state."\n entryUUID: ".$controls[0]->entryUUID."\n cookie: ".$controls[0]->cookie."\n";
} elsif ($controls[0]->isa('Net::LDAP::Control::SyncDone')) {
print "Received Sync Done Control\n";
print ' Cookie: '.$controls[0]->cookie."\n refreshDeletes: ".$controls[0]->refreshDeletes."\n";
} else {
print Dumper($controls[0]);
}
}
我创建了一个新问题,询问如何使用 .Net 获取同步信息消息。
我在 Ubuntu 19.04 VM 上设置了我的 OpenLDAP 服务器并允许复制(使用本教程:https://help.ubuntu.com/lts/serverguide/openldap-server.html#openldap-server-replication)。复制的一切似乎都没问题。 我没有设置消费者服务器,因为我的代码将充当一个消费者服务器,定期拉取修改后的元素。
modified/added 条目已正确检索,但我想获取已删除的项目,但我似乎无法让它工作。
如 RFC https://www.rfc-editor.org/rfc/rfc4533#section-3.3.2 所述,我应该收到一条包含名为“syncUUIDs”的属性的同步信息消息
syncUUIDs contain a set of UUIDs of the entries and references that have been deleted from the content since the last Sync Operation
我的同步请求控件初始化
syncRequestValue = BerConverter.Encode("{iob}", new object[] { refreshOnly, cookieSrc, true });
testdsrc = new DirectoryControl("1.3.6.1.4.1.4203.1.9.1.1", syncRequestValue, true, true);
将控件添加到请求中,然后发送。
request.Controls.Add(testdsrc);
connection.SendRequest(request);
response = (SearchResponse)connection.SendRequest(request);
获取条目,这里我删除了1个条目,修改了1个并添加了1个,我只得到了2个条目(added/modified个)
entries = response.Entries;
if (response.Entries.Count > 0)
{
object[] controlvalue = BerConverter.Decode("{Ob}",
response.Controls[0].GetValue());
cookieSrc = (byte[])controlvalue[0];
var refreshDeletes = (bool)controlvalue[1];
File.WriteAllBytes(strFileName, cookieSrc);
}
你知道它是来自我的 LDAP 服务器的配置还是我的 C# 代码?
不知道是不是:
- 我的服务器发送了正确的响应,但 SearchResponse class 不知道如何解释它
或
- 如果我的服务器配置错误并且根本不发送已删除条目的列表...
通过在我的 OpenLdap 服务器上添加 "sync" 日志级别,我能够看到发送了具有正确 OID 的中间消息。
slapd debug conn=1131 fd=15 ACCEPT from IP=x.x.x.x (IP=0.0.0.0:389)
slapd debug conn=1131 op=0 BIND dn="cn=admin,dc=example,dc=com" method=128
slapd debug conn=1131 op=0 BIND dn="cn=admin,dc=example,dc=com" mech=SIMPLE ssf=0
slapd debug conn=1131 op=0 RESULT tag=97 err=0 text=
slapd debug conn=1131 op=1 SRCH base="dc=example,dc=com" scope=2 deref=0 filter="(objectClass=*)"
slapd debug conn=1131 op=1 SRCH attr=dn objectClass cn displayName
**slapd debug conn=1131 op=1 INTERM oid=1.3.6.1.4.1.4203.1.9.1.4**
slapd debug conn=1131 op=1 ENTRY dn="ou=uni,dc=example,dc=com"
slapd debug syncprov_search_response: cookie=rid=000,csn=20190924091959.141380Z#000000#000#000000
slapd debug conn=1131 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
slapd debug conn=1131 op=2 UNBIND
slapd debug conn=1131 fd=15 closed
通过使用 Perl 脚本和 Perl Net::LDAP 库,我能够看到响应值包含已删除条目的 UUIDS。
我现在知道我的服务器已正确配置,但我不知道如何使用 .NET 获取 UUID
use Net::LDAP;
use Net::LDAP::Control::SyncRequest;
use Net::LDAP::Intermediate::SyncInfo;
use Net::LDAP::Constant qw(
LDAP_SYNC_REFRESH_ONLY
LDAP_SYNC_REFRESH_AND_PERSIST
LDAP_SUCCESS );
use Data::Dumper qw(Dumper);
$ldap = Net::LDAP->new( "127.0.0.1:389" ) or die($@);
$req = Net::LDAP::Control::SyncRequest->new( mode => LDAP_SYNC_REFRESH_ONLY, cookie => "rid=000,csn=20190912114502.963050Z#000000#000#000000" );
my $mesg = $ldap->search(base=> 'dc=example,dc=com',
scope => 'sub',
control => [ $req ],
callback => \&searchCallback, # call for each entry
filter => "(objectClass=*)",
attrs => [ '*']);
print "\n==========\n";
print Dumper($mesg);
sub searchCallback {
my $message = shift;
my $entry = shift;
my @controls = $message->control;
print Dumper($message);
print "\n==========\n";
my $count = scalar(@controls);
print " $count controls in response\n";
if ( $count == 0 ) {
if ($message->isa('Net::LDAP::Intermediate::SyncInfo')) {
print "Received Sync Info message\n";
}
return;
}
if (!defined($controls[0]) ) {
print " control 0 is undefined\n";
return;
}
if ($controls[0]->isa('Net::LDAP::Control::SyncState')) {
print "Received Sync State Control\n";
print $entry->dn()."\n";
#print Dumper($controls[0]->entryUUID);
print 'State: '.$controls[0]->state."\n entryUUID: ".$controls[0]->entryUUID."\n cookie: ".$controls[0]->cookie."\n";
} elsif ($controls[0]->isa('Net::LDAP::Control::SyncDone')) {
print "Received Sync Done Control\n";
print ' Cookie: '.$controls[0]->cookie."\n refreshDeletes: ".$controls[0]->refreshDeletes."\n";
} else {
print Dumper($controls[0]);
}
}
我创建了一个新问题,询问如何使用 .Net 获取同步信息消息。