mirror of
https://git.centos.org/rpms/389-ds-base.git
synced 2025-02-23 16:22:54 +00:00
150 lines
4.5 KiB
Diff
150 lines
4.5 KiB
Diff
![]() |
From 6361810037bc32c22e3e00a16bc53b34d0b0d610 Mon Sep 17 00:00:00 2001
|
||
|
From: Mark Reynolds <mreynolds@redhat.com>
|
||
|
Date: Mon, 9 Jul 2018 15:50:09 -0400
|
||
|
Subject: [PATCH] Ticket 49840 - ds-replcheck command returns traceback errors
|
||
|
against ldif files having garbage content when run in offline mode
|
||
|
|
||
|
Description: Added a basic check to see if the LDIF files are actually
|
||
|
LDIF files. Also added checks that the database RUV are
|
||
|
present as well.
|
||
|
|
||
|
https://pagure.io/389-ds-base/issue/49840
|
||
|
|
||
|
Reviewed by: spichugi(Thanks!)
|
||
|
|
||
|
(cherry picked from commit 60cb52040704686d9541a2e2eb2765d86cb10af2)
|
||
|
---
|
||
|
ldap/admin/src/scripts/ds-replcheck | 53 +++++++++++++++++++++++------
|
||
|
1 file changed, 43 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/ldap/admin/src/scripts/ds-replcheck b/ldap/admin/src/scripts/ds-replcheck
|
||
|
index 62f911034..5c195f983 100755
|
||
|
--- a/ldap/admin/src/scripts/ds-replcheck
|
||
|
+++ b/ldap/admin/src/scripts/ds-replcheck
|
||
|
@@ -10,18 +10,19 @@
|
||
|
#
|
||
|
|
||
|
import os
|
||
|
+import sys
|
||
|
import re
|
||
|
import time
|
||
|
import ldap
|
||
|
import ldapurl
|
||
|
import argparse
|
||
|
import getpass
|
||
|
-
|
||
|
+from ldif import LDIFRecordList
|
||
|
from ldap.ldapobject import SimpleLDAPObject
|
||
|
from ldap.cidict import cidict
|
||
|
from ldap.controls import SimplePagedResultsControl
|
||
|
|
||
|
-VERSION = "1.3"
|
||
|
+VERSION = "1.4"
|
||
|
RUV_FILTER = '(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))'
|
||
|
LDAP = 'ldap'
|
||
|
LDAPS = 'ldaps'
|
||
|
@@ -386,14 +387,17 @@ def ldif_search(LDIF, dn):
|
||
|
return result
|
||
|
|
||
|
|
||
|
-def get_dns(LDIF, opts):
|
||
|
+def get_dns(LDIF, filename, opts):
|
||
|
''' Get all the DN's from an LDIF file
|
||
|
'''
|
||
|
dns = []
|
||
|
found = False
|
||
|
+ found_ruv = False
|
||
|
+ LDIF.seek(0)
|
||
|
for line in LDIF:
|
||
|
if line.startswith('dn: ') and line[4:].startswith('nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff'):
|
||
|
opts['ruv_dn'] = line[4:].lower().strip()
|
||
|
+ found_ruv = True
|
||
|
elif line.startswith('dn: '):
|
||
|
found = True
|
||
|
dn = line[4:].lower().strip()
|
||
|
@@ -407,6 +411,14 @@ def get_dns(LDIF, opts):
|
||
|
found = False
|
||
|
dns.append(dn)
|
||
|
|
||
|
+ if not found_ruv:
|
||
|
+ print('Failed to find the database RUV in the LDIF file: ' + filename + ', the LDIF ' +
|
||
|
+ 'file must contain replication state information.')
|
||
|
+ dns = None
|
||
|
+ else:
|
||
|
+ # All good, reset cursor
|
||
|
+ LDIF.seek(0)
|
||
|
+
|
||
|
return dns
|
||
|
|
||
|
|
||
|
@@ -415,6 +427,7 @@ def get_ldif_ruv(LDIF, opts):
|
||
|
'''
|
||
|
LDIF.seek(0)
|
||
|
result = ldif_search(LDIF, opts['ruv_dn'])
|
||
|
+ LDIF.seek(0) # Reset cursor
|
||
|
return result['entry'].data['nsds50ruv']
|
||
|
|
||
|
|
||
|
@@ -549,6 +562,7 @@ def do_offline_report(opts, output_file=None):
|
||
|
rconflicts = []
|
||
|
rtombstones = 0
|
||
|
mtombstones = 0
|
||
|
+ idx = 0
|
||
|
|
||
|
# Open LDIF files
|
||
|
try:
|
||
|
@@ -561,12 +575,36 @@ def do_offline_report(opts, output_file=None):
|
||
|
RLDIF = open(opts['rldif'], "r")
|
||
|
except Exception as e:
|
||
|
print('Failed to open Replica LDIF: ' + str(e))
|
||
|
+ MLDIF.close()
|
||
|
+ return None
|
||
|
+
|
||
|
+ # Verify LDIF Files
|
||
|
+ try:
|
||
|
+ print("Validating Master ldif file ({})...".format(opts['mldif']))
|
||
|
+ LDIFRecordList(MLDIF).parse()
|
||
|
+ except ValueError:
|
||
|
+ print('Master LDIF file in invalid, aborting...')
|
||
|
+ MLDIF.close()
|
||
|
+ RLDIF.close()
|
||
|
+ return None
|
||
|
+ try:
|
||
|
+ print("Validating Replica ldif file ({})...".format(opts['rldif']))
|
||
|
+ LDIFRecordList(RLDIF).parse()
|
||
|
+ except ValueError:
|
||
|
+ print('Replica LDIF file is invalid, aborting...')
|
||
|
+ MLDIF.close()
|
||
|
+ RLDIF.close()
|
||
|
return None
|
||
|
|
||
|
# Get all the dn's, and entry counts
|
||
|
print ("Gathering all the DN's...")
|
||
|
- master_dns = get_dns(MLDIF, opts)
|
||
|
- replica_dns = get_dns(RLDIF, opts)
|
||
|
+ master_dns = get_dns(MLDIF, opts['mldif'], opts)
|
||
|
+ replica_dns = get_dns(RLDIF, opts['rldif'], opts)
|
||
|
+ if master_dns is None or replica_dns is None:
|
||
|
+ print("Aborting scan...")
|
||
|
+ MLDIF.close()
|
||
|
+ RLDIF.close()
|
||
|
+ sys.exit(1)
|
||
|
m_count = len(master_dns)
|
||
|
r_count = len(replica_dns)
|
||
|
|
||
|
@@ -575,11 +613,6 @@ def do_offline_report(opts, output_file=None):
|
||
|
opts['master_ruv'] = get_ldif_ruv(MLDIF, opts)
|
||
|
opts['replica_ruv'] = get_ldif_ruv(RLDIF, opts)
|
||
|
|
||
|
- # Reset the cursors
|
||
|
- idx = 0
|
||
|
- MLDIF.seek(idx)
|
||
|
- RLDIF.seek(idx)
|
||
|
-
|
||
|
""" Compare the master entries with the replica's. Take our list of dn's from
|
||
|
the master ldif and get that entry( dn) from the master and replica ldif. In
|
||
|
this phase we keep keep track of conflict/tombstone counts, and we check for
|
||
|
--
|
||
|
2.17.1
|
||
|
|