[389-ds-base] branch 389-ds-base-1.4.2 updated: Bump version to 1.4.2.14
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.2
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.2 by this push:
new 5ac5b02 Bump version to 1.4.2.14
5ac5b02 is described below
commit 5ac5b02ceb94e358d4eea2e8a910396f4b4496ec
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri May 29 17:33:57 2020 -0400
Bump version to 1.4.2.14
---
VERSION.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION.sh b/VERSION.sh
index 80ded3d..4279677 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=4
-VERSION_MAINT=2.13
+VERSION_MAINT=2.14
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.3 updated: Bump version to 1.4.3.9
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.3
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.3 by this push:
new 3eb8617 Bump version to 1.4.3.9
3eb8617 is described below
commit 3eb8617f606f04540f07508be9b9e9e2fac609bc
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri May 29 17:10:41 2020 -0400
Bump version to 1.4.3.9
---
VERSION.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION.sh b/VERSION.sh
index 5b5e12a..bf17b8e 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=4
-VERSION_MAINT=3.8
+VERSION_MAINT=3.9
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch master updated: Bump version to 1.4.4.3
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new 7b79b89 Bump version to 1.4.4.3
7b79b89 is described below
commit 7b79b89c19d75d72a1e0323e81e0ad7bb43b6342
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri May 29 16:44:12 2020 -0400
Bump version to 1.4.4.3
---
VERSION.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION.sh b/VERSION.sh
index 561818d..f84f24b 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=4
-VERSION_MAINT=4.2
+VERSION_MAINT=4.3
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.3 updated: Issue 50931 - RFE AD filter rewriter for ObjectCategory
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
vashirov pushed a commit to branch 389-ds-base-1.4.3
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.3 by this push:
new dc8e260 Issue 50931 - RFE AD filter rewriter for ObjectCategory
dc8e260 is described below
commit dc8e260c1f6a539cdca6ee42a24a178a2b247dcd
Author: Viktor Ashirov <vashirov(a)redhat.com>
AuthorDate: Wed May 27 15:22:18 2020 +0200
Issue 50931 - RFE AD filter rewriter for ObjectCategory
Bug Description:
ASAN build fails on RHEL due to linking issues
Fix Description:
Add missing libslapd.la for librewriters.la
Relates: https://pagure.io/389-ds-base/issue/50931
Reviewed by: tbordaz (Thanks!)
---
Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.am b/Makefile.am
index 2309f30..0e5f04f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1159,7 +1159,7 @@ librewriters_la_SOURCES = \
librewriters_la_LDFLAGS = $(AM_LDFLAGS)
librewriters_la_CPPFLAGS = $(AM_CPPFLAGS) $(REWRITERS_INCLUDES) $(DSPLUGIN_CPPFLAGS)
-librewriters_la_LIBADD = $(NSS_LINK) $(NSPR_LINK)
+librewriters_la_LIBADD = libslapd.la $(NSS_LINK) $(NSPR_LINK)
#------------------------
# libsvrcore
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.2 updated: Issue 51113 - Allow using uid for replication manager entry
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.2
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.2 by this push:
new dff89df Issue 51113 - Allow using uid for replication manager entry
dff89df is described below
commit dff89dfa2d532325a35d8dbf793e9f51f9c769be
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue May 26 17:03:11 2020 -0400
Issue 51113 - Allow using uid for replication manager entry
Bug Description: Currently it was hardcoded to only allow "cn" as
the rdn attribute for the replication manager entry.
Fix description: Allow setting the rdn attribute of the replication
manager DS ldap object, and include the schema that
allows "uid".
relates: https://pagure.io/389-ds-base/issue/51113
Reviewed by: spichugi & firstyear(Thanks!!)
---
src/lib389/lib389/cli_conf/replication.py | 53 ++++++++++++++++---------------
src/lib389/lib389/replica.py | 11 ++++---
2 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py
index 09cb9b4..b9bc3d2 100644
--- a/src/lib389/lib389/cli_conf/replication.py
+++ b/src/lib389/lib389/cli_conf/replication.py
@@ -199,19 +199,21 @@ def enable_replication(inst, basedn, log, args):
# Create replication manager if password was provided
if args.bind_dn and args.bind_passwd:
- cn_rdn = args.bind_dn.split(",", 1)[0]
- cn_val = cn_rdn.split("=", 1)[1]
- manager = BootstrapReplicationManager(inst, dn=args.bind_dn)
+ rdn = args.bind_dn.split(",", 1)[0]
+ rdn_attr, rdn_val = rdn.split("=", 1)
+ manager = BootstrapReplicationManager(inst, dn=args.bind_dn, rdn_attr=rdn_attr)
try:
manager.create(properties={
- 'cn': cn_val,
+ 'cn': rdn_val,
+ 'uid': rdn_val,
'userPassword': args.bind_passwd
})
except ldap.ALREADY_EXISTS:
# Already there, but could have different password. Delete and recreate
manager.delete()
manager.create(properties={
- 'cn': cn_val,
+ 'cn': rdn_val,
+ 'uid': rdn_val,
'userPassword': args.bind_passwd
})
except ldap.NO_SUCH_OBJECT:
@@ -511,22 +513,23 @@ def get_cl(inst, basedn, log, args):
def create_repl_manager(inst, basedn, log, args):
- manager_cn = "replication manager"
+ manager_name = "replication manager"
repl_manager_password = ""
repl_manager_password_confirm = ""
if args.name:
- manager_cn = args.name
-
- if is_a_dn(manager_cn):
- # A full DN was provided, make sure it uses "cn" for the RDN
- if manager_cn.split("=", 1)[0].lower() != "cn":
- raise ValueError("Replication manager DN must use \"cn\" for the rdn attribute")
- manager_dn = manager_cn
- manager_rdn = manager_dn.split(",", 1)[0]
- manager_cn = manager_rdn.split("=", 1)[1]
+ manager_name = args.name
+
+ if is_a_dn(manager_name):
+ # A full DN was provided
+ manager_dn = manager_name
+ manager_rdn = manager_name.split(",", 1)[0]
+ manager_attr, manager_name = manager_rdn.split("=", 1)
+ if manager_attr.lower() not in ['cn', 'uid']:
+ raise ValueError(f'The RDN attribute "{manager_attr}" is not allowed, you must use "cn" or "uid"')
else:
- manager_dn = "cn={},cn=config".format(manager_cn)
+ manager_dn = "cn={},cn=config".format(manager_name)
+ manager_attr = "cn"
if args.passwd:
repl_manager_password = args.passwd
@@ -544,10 +547,11 @@ def create_repl_manager(inst, basedn, log, args):
repl_manager_password = ""
repl_manager_password_confirm = ""
- manager = BootstrapReplicationManager(inst, dn=manager_dn)
+ manager = BootstrapReplicationManager(inst, dn=manager_dn, rdn_attr=manager_attr)
try:
manager.create(properties={
- 'cn': manager_cn,
+ 'cn': manager_name,
+ 'uid': manager_name,
'userPassword': repl_manager_password
})
if args.suffix:
@@ -564,7 +568,8 @@ def create_repl_manager(inst, basedn, log, args):
# Already there, but could have different password. Delete and recreate
manager.delete()
manager.create(properties={
- 'cn': manager_cn,
+ 'cn': manager_name,
+ 'uid': manager_name,
'userPassword': repl_manager_password
})
if args.suffix:
@@ -954,6 +959,7 @@ def get_winsync_agmt_status(inst, basedn, log, args):
status = agmt.status(winsync=True, use_json=args.json)
log.info(status)
+
#
# Tasks
#
@@ -1347,8 +1353,7 @@ def create_parser(subparsers):
agmt_set_parser.add_argument('--wait-async-results', help="The amount of time in milliseconds the server waits if "
"the consumer is not ready before resending data")
agmt_set_parser.add_argument('--busy-wait-time', help="The amount of time in seconds a supplier should wait after "
- "a consumer sends back a busy response before making another "
- "attempt to acquire access.")
+ "a consumer sends back a busy response before making another attempt to acquire access.")
agmt_set_parser.add_argument('--session-pause-time', help="The amount of time in seconds a supplier should wait between update sessions.")
agmt_set_parser.add_argument('--flow-control-window', help="Sets the maximum number of entries and updates sent by a supplier, which are not acknowledged by the consumer.")
agmt_set_parser.add_argument('--flow-control-pause', help="The time in milliseconds to pause after reaching the number of entries and updates set in \"--flow-control-window\"")
@@ -1438,8 +1443,7 @@ def create_parser(subparsers):
winsync_agmt_add_parser.add_argument('--subtree-pair', help="Set the subtree pair: <DS_SUBTREE>:<WINDOWS_SUBTREE>")
winsync_agmt_add_parser.add_argument('--conn-timeout', help="The timeout used for replicaton connections")
winsync_agmt_add_parser.add_argument('--busy-wait-time', help="The amount of time in seconds a supplier should wait after "
- "a consumer sends back a busy response before making another "
- "attempt to acquire access.")
+ "a consumer sends back a busy response before making another attempt to acquire access.")
winsync_agmt_add_parser.add_argument('--session-pause-time', help="The amount of time in seconds a supplier should wait between update sessions.")
winsync_agmt_add_parser.add_argument('--init', action='store_true', default=False, help="Initialize the agreement after creating it.")
@@ -1468,8 +1472,7 @@ def create_parser(subparsers):
winsync_agmt_set_parser.add_argument('--subtree-pair', help="Set the subtree pair: <DS_SUBTREE>:<WINDOWS_SUBTREE>")
winsync_agmt_set_parser.add_argument('--conn-timeout', help="The timeout used for replicaton connections")
winsync_agmt_set_parser.add_argument('--busy-wait-time', help="The amount of time in seconds a supplier should wait after "
- "a consumer sends back a busy response before making another "
- "attempt to acquire access.")
+ "a consumer sends back a busy response before making another attempt to acquire access.")
winsync_agmt_set_parser.add_argument('--session-pause-time', help="The amount of time in seconds a supplier should wait between update sessions.")
# Get
diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
index e3fc7fe..f8adb3c 100644
--- a/src/lib389/lib389/replica.py
+++ b/src/lib389/lib389/replica.py
@@ -1779,15 +1779,18 @@ class BootstrapReplicationManager(DSLdapObject):
:type instance: lib389.DirSrv
:param dn: The dn to create
:type dn: str
+ :param rdn_attr: The attribute to use for the RDN
+ :type rdn_attr: str
"""
- def __init__(self, instance, dn='cn=replication manager,cn=config'):
+ def __init__(self, instance, dn='cn=replication manager,cn=config', rdn_attr='cn'):
super(BootstrapReplicationManager, self).__init__(instance, dn)
- self._rdn_attribute = 'cn'
+ self._rdn_attribute = rdn_attr
self._must_attributes = ['cn', 'userPassword']
self._create_objectclasses = [
'top',
- 'netscapeServer',
- 'nsAccount'
+ 'inetUser', # for uid
+ 'netscapeServer', # for cn
+ 'nsAccount', # for authentication attributes
]
if ds_is_older('1.4.0'):
self._create_objectclasses.remove('nsAccount')
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.3 updated: Issue 51113 - Allow using uid for replication manager entry
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.3
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.3 by this push:
new f910aa5 Issue 51113 - Allow using uid for replication manager entry
f910aa5 is described below
commit f910aa5f3c01b48e82631e1625279ee8e19e2b24
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue May 26 17:03:11 2020 -0400
Issue 51113 - Allow using uid for replication manager entry
Bug Description: Currently it was hardcoded to only allow "cn" as
the rdn attribute for the replication manager entry.
Fix description: Allow setting the rdn attribute of the replication
manager DS ldap object, and include the schema that
allows "uid".
relates: https://pagure.io/389-ds-base/issue/51113
Reviewed by: spichugi & firstyear(Thanks!!)
---
src/lib389/lib389/cli_conf/replication.py | 53 ++++++++++++++++---------------
src/lib389/lib389/replica.py | 11 ++++---
2 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py
index 09cb9b4..b9bc3d2 100644
--- a/src/lib389/lib389/cli_conf/replication.py
+++ b/src/lib389/lib389/cli_conf/replication.py
@@ -199,19 +199,21 @@ def enable_replication(inst, basedn, log, args):
# Create replication manager if password was provided
if args.bind_dn and args.bind_passwd:
- cn_rdn = args.bind_dn.split(",", 1)[0]
- cn_val = cn_rdn.split("=", 1)[1]
- manager = BootstrapReplicationManager(inst, dn=args.bind_dn)
+ rdn = args.bind_dn.split(",", 1)[0]
+ rdn_attr, rdn_val = rdn.split("=", 1)
+ manager = BootstrapReplicationManager(inst, dn=args.bind_dn, rdn_attr=rdn_attr)
try:
manager.create(properties={
- 'cn': cn_val,
+ 'cn': rdn_val,
+ 'uid': rdn_val,
'userPassword': args.bind_passwd
})
except ldap.ALREADY_EXISTS:
# Already there, but could have different password. Delete and recreate
manager.delete()
manager.create(properties={
- 'cn': cn_val,
+ 'cn': rdn_val,
+ 'uid': rdn_val,
'userPassword': args.bind_passwd
})
except ldap.NO_SUCH_OBJECT:
@@ -511,22 +513,23 @@ def get_cl(inst, basedn, log, args):
def create_repl_manager(inst, basedn, log, args):
- manager_cn = "replication manager"
+ manager_name = "replication manager"
repl_manager_password = ""
repl_manager_password_confirm = ""
if args.name:
- manager_cn = args.name
-
- if is_a_dn(manager_cn):
- # A full DN was provided, make sure it uses "cn" for the RDN
- if manager_cn.split("=", 1)[0].lower() != "cn":
- raise ValueError("Replication manager DN must use \"cn\" for the rdn attribute")
- manager_dn = manager_cn
- manager_rdn = manager_dn.split(",", 1)[0]
- manager_cn = manager_rdn.split("=", 1)[1]
+ manager_name = args.name
+
+ if is_a_dn(manager_name):
+ # A full DN was provided
+ manager_dn = manager_name
+ manager_rdn = manager_name.split(",", 1)[0]
+ manager_attr, manager_name = manager_rdn.split("=", 1)
+ if manager_attr.lower() not in ['cn', 'uid']:
+ raise ValueError(f'The RDN attribute "{manager_attr}" is not allowed, you must use "cn" or "uid"')
else:
- manager_dn = "cn={},cn=config".format(manager_cn)
+ manager_dn = "cn={},cn=config".format(manager_name)
+ manager_attr = "cn"
if args.passwd:
repl_manager_password = args.passwd
@@ -544,10 +547,11 @@ def create_repl_manager(inst, basedn, log, args):
repl_manager_password = ""
repl_manager_password_confirm = ""
- manager = BootstrapReplicationManager(inst, dn=manager_dn)
+ manager = BootstrapReplicationManager(inst, dn=manager_dn, rdn_attr=manager_attr)
try:
manager.create(properties={
- 'cn': manager_cn,
+ 'cn': manager_name,
+ 'uid': manager_name,
'userPassword': repl_manager_password
})
if args.suffix:
@@ -564,7 +568,8 @@ def create_repl_manager(inst, basedn, log, args):
# Already there, but could have different password. Delete and recreate
manager.delete()
manager.create(properties={
- 'cn': manager_cn,
+ 'cn': manager_name,
+ 'uid': manager_name,
'userPassword': repl_manager_password
})
if args.suffix:
@@ -954,6 +959,7 @@ def get_winsync_agmt_status(inst, basedn, log, args):
status = agmt.status(winsync=True, use_json=args.json)
log.info(status)
+
#
# Tasks
#
@@ -1347,8 +1353,7 @@ def create_parser(subparsers):
agmt_set_parser.add_argument('--wait-async-results', help="The amount of time in milliseconds the server waits if "
"the consumer is not ready before resending data")
agmt_set_parser.add_argument('--busy-wait-time', help="The amount of time in seconds a supplier should wait after "
- "a consumer sends back a busy response before making another "
- "attempt to acquire access.")
+ "a consumer sends back a busy response before making another attempt to acquire access.")
agmt_set_parser.add_argument('--session-pause-time', help="The amount of time in seconds a supplier should wait between update sessions.")
agmt_set_parser.add_argument('--flow-control-window', help="Sets the maximum number of entries and updates sent by a supplier, which are not acknowledged by the consumer.")
agmt_set_parser.add_argument('--flow-control-pause', help="The time in milliseconds to pause after reaching the number of entries and updates set in \"--flow-control-window\"")
@@ -1438,8 +1443,7 @@ def create_parser(subparsers):
winsync_agmt_add_parser.add_argument('--subtree-pair', help="Set the subtree pair: <DS_SUBTREE>:<WINDOWS_SUBTREE>")
winsync_agmt_add_parser.add_argument('--conn-timeout', help="The timeout used for replicaton connections")
winsync_agmt_add_parser.add_argument('--busy-wait-time', help="The amount of time in seconds a supplier should wait after "
- "a consumer sends back a busy response before making another "
- "attempt to acquire access.")
+ "a consumer sends back a busy response before making another attempt to acquire access.")
winsync_agmt_add_parser.add_argument('--session-pause-time', help="The amount of time in seconds a supplier should wait between update sessions.")
winsync_agmt_add_parser.add_argument('--init', action='store_true', default=False, help="Initialize the agreement after creating it.")
@@ -1468,8 +1472,7 @@ def create_parser(subparsers):
winsync_agmt_set_parser.add_argument('--subtree-pair', help="Set the subtree pair: <DS_SUBTREE>:<WINDOWS_SUBTREE>")
winsync_agmt_set_parser.add_argument('--conn-timeout', help="The timeout used for replicaton connections")
winsync_agmt_set_parser.add_argument('--busy-wait-time', help="The amount of time in seconds a supplier should wait after "
- "a consumer sends back a busy response before making another "
- "attempt to acquire access.")
+ "a consumer sends back a busy response before making another attempt to acquire access.")
winsync_agmt_set_parser.add_argument('--session-pause-time', help="The amount of time in seconds a supplier should wait between update sessions.")
# Get
diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
index e3fc7fe..f8adb3c 100644
--- a/src/lib389/lib389/replica.py
+++ b/src/lib389/lib389/replica.py
@@ -1779,15 +1779,18 @@ class BootstrapReplicationManager(DSLdapObject):
:type instance: lib389.DirSrv
:param dn: The dn to create
:type dn: str
+ :param rdn_attr: The attribute to use for the RDN
+ :type rdn_attr: str
"""
- def __init__(self, instance, dn='cn=replication manager,cn=config'):
+ def __init__(self, instance, dn='cn=replication manager,cn=config', rdn_attr='cn'):
super(BootstrapReplicationManager, self).__init__(instance, dn)
- self._rdn_attribute = 'cn'
+ self._rdn_attribute = rdn_attr
self._must_attributes = ['cn', 'userPassword']
self._create_objectclasses = [
'top',
- 'netscapeServer',
- 'nsAccount'
+ 'inetUser', # for uid
+ 'netscapeServer', # for cn
+ 'nsAccount', # for authentication attributes
]
if ds_is_older('1.4.0'):
self._create_objectclasses.remove('nsAccount')
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.3.10 updated: Issue 51095 - abort operation if CSN can not be generated
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.3.10
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.3.10 by this push:
new 6f14ce5 Issue 51095 - abort operation if CSN can not be generated
6f14ce5 is described below
commit 6f14ce53317a9a7372a2165391437e8b94cd5c1a
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri May 22 10:42:11 2020 -0400
Issue 51095 - abort operation if CSN can not be generated
Bug Description: If we fail to get the system time then we were using an
uninitialized timespec struct which could lead to bizarre
times in CSN's.
Fix description: Check if the system time function fails, and if it does
then abort the update operation.
relates: https://pagure.io/389-ds-base/issue/51095
Reviewed by: firstyear & tbordaz(Thanks!!)
---
ldap/servers/plugins/replication/repl5.h | 2 +-
ldap/servers/plugins/replication/repl5_replica.c | 29 ++++++++++------
ldap/servers/slapd/back-ldbm/ldbm_add.c | 8 ++++-
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 9 ++++-
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 10 ++++--
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 8 ++++-
ldap/servers/slapd/csngen.c | 18 ++++++++--
ldap/servers/slapd/entrywsi.c | 15 +++++----
ldap/servers/slapd/slap.h | 2 +-
ldap/servers/slapd/slapi-plugin.h | 8 +++++
ldap/servers/slapd/slapi-private.h | 5 +--
ldap/servers/slapd/time.c | 43 +++++++++++++++++-------
12 files changed, 116 insertions(+), 41 deletions(-)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index b06c6fb..bdc5942 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -775,7 +775,7 @@ void replica_disable_replication(Replica *r, Object *r_obj);
int replica_start_agreement(Replica *r, Repl_Agmt *ra);
int windows_replica_start_agreement(Replica *r, Repl_Agmt *ra);
-CSN *replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn);
+int32_t replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
int replica_get_attr(Slapi_PBlock *pb, const char *type, void *value);
/* mapping tree extensions manipulation */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index cdbcde3..c1b3ed7 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -3976,10 +3976,9 @@ windows_replica_start_agreement(Replica *r, Repl_Agmt *ra)
* A callback function registered as op->o_csngen_handler and
* called by backend ops to generate opcsn.
*/
-CSN *
-replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
+int32_t
+replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn)
{
- CSN *opcsn = NULL;
Object *replica_obj;
replica_obj = replica_get_replica_for_op(pb);
@@ -3994,17 +3993,25 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
CSNGen *gen = (CSNGen *)object_get_data(gen_obj);
if (NULL != gen) {
/* The new CSN should be greater than the base CSN */
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
- if (csn_compare(opcsn, basecsn) <= 0) {
+ if (csngen_new_csn(gen, opcsn, PR_FALSE /* don't notify */) != CSN_SUCCESS) {
+ /* Failed to generate CSN we must abort */
+ object_release(gen_obj);
+ return -1;
+ }
+ if (csn_compare(*opcsn, basecsn) <= 0) {
char opcsnstr[CSN_STRSIZE], basecsnstr[CSN_STRSIZE];
char opcsn2str[CSN_STRSIZE];
- csn_as_string(opcsn, PR_FALSE, opcsnstr);
+ csn_as_string(*opcsn, PR_FALSE, opcsnstr);
csn_as_string(basecsn, PR_FALSE, basecsnstr);
- csn_free(&opcsn);
+ csn_free(opcsn);
csngen_adjust_time(gen, basecsn);
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
- csn_as_string(opcsn, PR_FALSE, opcsn2str);
+ if (csngen_new_csn(gen, opcsn, PR_FALSE /* don't notify */) != CSN_SUCCESS) {
+ /* Failed to generate CSN we must abort */
+ object_release(gen_obj);
+ return -1;
+ }
+ csn_as_string(*opcsn, PR_FALSE, opcsn2str);
slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name,
"replica_generate_next_csn - "
"opcsn=%s <= basecsn=%s, adjusted opcsn=%s\n",
@@ -4014,7 +4021,7 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
* Insert opcsn into the csn pending list.
* This is the notify effect in csngen_new_csn().
*/
- assign_csn_callback(opcsn, (void *)replica);
+ assign_csn_callback(*opcsn, (void *)replica);
}
object_release(gen_obj);
}
@@ -4023,7 +4030,7 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
object_release(replica_obj);
}
- return opcsn;
+ return 0;
}
/*
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index 264f0ce..09bfb84 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -644,7 +644,13 @@ ldbm_back_add(Slapi_PBlock *pb)
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL);
+ if (entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_add",
+ "failed to generate add CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
entry_set_csn(e, opcsn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 1ad8464..6c42290 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -463,7 +463,14 @@ replace_entry:
* by entry_assign_operation_csn() if the dn is in an
* updatable replica.
*/
- opcsn = entry_assign_operation_csn ( pb, e->ep_entry, NULL );
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_delete",
+ "failed to generate delete CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ retval = -1;
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
if (!is_fixup_operation) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index b0c477e..e9d7e87 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -598,12 +598,18 @@ ldbm_back_modify(Slapi_PBlock *pb)
goto error_return;
}
opcsn = operation_get_csn(operation);
- if (NULL == opcsn && operation->o_csngen_handler) {
+ if (opcsn == NULL && operation->o_csngen_handler) {
/*
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, NULL);
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modify",
+ "failed to generate modify CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn) {
entry_set_maxcsn(e->ep_entry, opcsn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 2669801..fde83c9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -543,7 +543,13 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL);
+ if (entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modrdn",
+ "failed to generate modrdn CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
entry_set_maxcsn(e->ep_entry, opcsn);
diff --git a/ldap/servers/slapd/csngen.c b/ldap/servers/slapd/csngen.c
index 68dbbda..b08d8b2 100644
--- a/ldap/servers/slapd/csngen.c
+++ b/ldap/servers/slapd/csngen.c
@@ -164,6 +164,7 @@ csngen_free(CSNGen **gen)
int
csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
{
+ struct timespec now = {0};
int rc = CSN_SUCCESS;
time_t cur_time;
int delta;
@@ -179,12 +180,25 @@ csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
return CSN_MEMORY_ERROR;
}
- slapi_rwlock_wrlock(gen->lock);
+ if ((rc = slapi_clock_gettime(&now)) != 0) {
+ /* Failed to get system time, we must abort */
+ slapi_log_err(SLAPI_LOG_ERR, "csngen_new_csn",
+ "Failed to get system time (%s)\n",
+ slapd_system_strerror(rc));
+ return CSN_TIME_ERROR;
+ }
+ cur_time = now.tv_sec;
- cur_time = slapi_current_utc_time();
+ slapi_rwlock_wrlock(gen->lock);
/* check if the time should be adjusted */
delta = cur_time - gen->state.sampled_time;
+ if (delta > _SEC_PER_DAY || delta < (-1 * _SEC_PER_DAY)) {
+ /* We had a jump larger than a day */
+ slapi_log_err(SLAPI_LOG_INFO, "csngen_new_csn",
+ "Detected large jump in CSN time. Delta: %d (current time: %ld vs previous time: %ld)\n",
+ delta, cur_time, gen->state.sampled_time);
+ }
if (delta > 0) {
rc = _csngen_adjust_local_time(gen, cur_time);
if (rc != CSN_SUCCESS) {
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 080eb15..12ac567 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -224,13 +224,12 @@ entry_add_rdn_csn(Slapi_Entry *e, const CSN *csn)
slapi_rdn_free(&rdn);
}
-CSN *
-entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry)
+int32_t
+entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn)
{
Slapi_Operation *op;
const CSN *basecsn = NULL;
const CSN *parententry_dncsn = NULL;
- CSN *opcsn = NULL;
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
@@ -252,14 +251,16 @@ entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parent
basecsn = parententry_dncsn;
}
}
- opcsn = op->o_csngen_handler(pb, basecsn);
+ if(op->o_csngen_handler(pb, basecsn, opcsn) != 0) {
+ return -1;
+ }
- if (NULL != opcsn) {
- operation_set_csn(op, opcsn);
+ if (*opcsn) {
+ operation_set_csn(op, *opcsn);
}
}
- return opcsn;
+ return 0;
}
/*
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 4c53d43..1d0a9cb 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1464,7 +1464,7 @@ struct op;
typedef void (*result_handler)(struct conn *, struct op *, int, char *, char *, int, struct berval **);
typedef int (*search_entry_handler)(Slapi_Backend *, struct conn *, struct op *, struct slapi_entry *);
typedef int (*search_referral_handler)(Slapi_Backend *, struct conn *, struct op *, struct berval **);
-typedef CSN *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn);
+typedef int32_t *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
typedef int (*replica_attr_handler)(Slapi_PBlock *pb, const char *type, void **value);
/*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 865d83b..ea9bcf8 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6773,6 +6773,14 @@ int slapi_reslimit_get_integer_limit(Slapi_Connection *conn, int handle, int *li
time_t slapi_current_time(void) __attribute__((deprecated));
/**
+ * Get the system time and check for errors. Return
+ *
+ * \param tp - a timespec struct where the system time is set
+ * \return result code, upon success tp is set to the system time
+ */
+int32_t slapi_clock_gettime(struct timespec *tp);
+
+/**
* Returns the current system time as a hr clock relative to uptime
* This means the clock is not affected by timezones
* which can normally cause issues with timers. Additionally, this
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index d676486..f37cfcd 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -227,7 +227,8 @@ enum
CSN_INVALID_PARAMETER, /* invalid function argument */
CSN_INVALID_FORMAT, /* invalid state format */
CSN_LDAP_ERROR, /* LDAP operation failed */
- CSN_NSPR_ERROR /* NSPR API failure */
+ CSN_NSPR_ERROR, /* NSPR API failure */
+ CSN_TIME_ERROR /* Error generating new CSN due to clock failure */
};
typedef struct csngen CSNGen;
@@ -320,7 +321,7 @@ int slapi_entries_diff(Slapi_Entry **old_entries, Slapi_Entry **new_entries, int
void set_attr_to_protected_list(char *attr, int flag);
/* entrywsi.c */
-CSN *entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry);
+int32_t entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn);
const CSN *entry_get_maxcsn(const Slapi_Entry *entry);
void entry_set_maxcsn(Slapi_Entry *entry, const CSN *csn);
const CSN *entry_get_dncsn(const Slapi_Entry *entry);
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index 8048a33..5455384 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -61,6 +61,25 @@ poll_current_time()
return 0;
}
+/*
+ * Check if the time function returns an error. If so return the errno
+ */
+int32_t
+slapi_clock_gettime(struct timespec *tp)
+{
+ int32_t rc = 0;
+
+ PR_ASSERT(tp && tp->tv_nsec == 0 && tp->tv_sec == 0);
+
+ if (clock_gettime(CLOCK_REALTIME, tp) != 0) {
+ rc = errno;
+ }
+
+ PR_ASSERT(rc == 0);
+
+ return rc;
+}
+
time_t
current_time(void)
{
@@ -69,7 +88,7 @@ current_time(void)
* but this should be removed in favour of the
* more accurately named slapi_current_utc_time
*/
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_REALTIME, &now);
return now.tv_sec;
}
@@ -83,7 +102,7 @@ slapi_current_time(void)
struct timespec
slapi_current_rel_time_hr(void)
{
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_MONOTONIC, &now);
return now;
}
@@ -91,7 +110,7 @@ slapi_current_rel_time_hr(void)
struct timespec
slapi_current_utc_time_hr(void)
{
- struct timespec ltnow;
+ struct timespec ltnow = {0};
clock_gettime(CLOCK_REALTIME, <now);
return ltnow;
}
@@ -99,7 +118,7 @@ slapi_current_utc_time_hr(void)
time_t
slapi_current_utc_time(void)
{
- struct timespec ltnow;
+ struct timespec ltnow = {0};
clock_gettime(CLOCK_REALTIME, <now);
return ltnow.tv_sec;
}
@@ -108,8 +127,8 @@ void
slapi_timestamp_utc_hr(char *buf, size_t bufsize)
{
PR_ASSERT(bufsize >= SLAPI_TIMESTAMP_BUFSIZE);
- struct timespec ltnow;
- struct tm utctm;
+ struct timespec ltnow = {0};
+ struct tm utctm = {0};
clock_gettime(CLOCK_REALTIME, <now);
gmtime_r(&(ltnow.tv_sec), &utctm);
strftime(buf, bufsize, "%Y%m%d%H%M%SZ", &utctm);
@@ -140,7 +159,7 @@ format_localTime_log(time_t t, int initsize __attribute__((unused)), char *buf,
{
long tz;
- struct tm *tmsp, tms;
+ struct tm *tmsp, tms = {0};
char tbuf[*bufsize];
char sign;
/* make sure our buffer will be big enough. Need at least 29 */
@@ -191,7 +210,7 @@ format_localTime_hr_log(time_t t, long nsec, int initsize __attribute__((unused)
{
long tz;
- struct tm *tmsp, tms;
+ struct tm *tmsp, tms = {0};
char tbuf[*bufsize];
char sign;
/* make sure our buffer will be big enough. Need at least 39 */
@@ -278,7 +297,7 @@ slapi_timespec_expire_check(struct timespec *expire)
if (expire->tv_sec == 0 && expire->tv_nsec == 0) {
return TIMER_CONTINUE;
}
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_MONOTONIC, &now);
if (now.tv_sec > expire->tv_sec ||
(expire->tv_sec == now.tv_sec && now.tv_sec > expire->tv_nsec)) {
@@ -293,7 +312,7 @@ format_localTime(time_t from)
in the syntax of a generalizedTime, except without the time zone. */
{
char *into;
- struct tm t;
+ struct tm t = {0};
localtime_r(&from, &t);
@@ -362,7 +381,7 @@ format_genTime(time_t from)
in the syntax of a generalizedTime. */
{
char *into;
- struct tm t;
+ struct tm t = {0};
gmtime_r(&from, &t);
into = slapi_ch_malloc(SLAPI_TIMESTAMP_BUFSIZE);
@@ -382,7 +401,7 @@ time_t
read_genTime(struct berval *from)
{
struct tm t = {0};
- time_t retTime;
+ time_t retTime = {0};
time_t diffsec = 0;
int i, gflag = 0, havesec = 0;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 51095 - abort operation if CSN can not be generated
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new b5d3327 Issue 51095 - abort operation if CSN can not be generated
b5d3327 is described below
commit b5d3327ce86296e7e872ff39223cc4a81a0935fc
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri May 22 10:42:11 2020 -0400
Issue 51095 - abort operation if CSN can not be generated
Bug Description: If we fail to get the system time then we were using an
uninitialized timespec struct which could lead to bizarre
times in CSN's.
Fix description: Check if the system time function fails, and if it does
then abort the update operation.
relates: https://pagure.io/389-ds-base/issue/51095
Reviewed by: firstyear & tbordaz(Thanks!!)
---
ldap/servers/plugins/replication/repl5.h | 2 +-
ldap/servers/plugins/replication/repl5_replica.c | 33 +++++++++++-------
ldap/servers/slapd/back-ldbm/ldbm_add.c | 8 ++++-
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 9 ++++-
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 10 ++++--
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 8 ++++-
ldap/servers/slapd/csngen.c | 18 ++++++++--
ldap/servers/slapd/entrywsi.c | 15 +++++----
ldap/servers/slapd/slap.h | 2 +-
ldap/servers/slapd/slapi-plugin.h | 8 +++++
ldap/servers/slapd/slapi-private.h | 5 +--
ldap/servers/slapd/time.c | 43 +++++++++++++++++-------
12 files changed, 118 insertions(+), 43 deletions(-)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 72b7089..6384717 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -776,7 +776,7 @@ void replica_disable_replication(Replica *r);
int replica_start_agreement(Replica *r, Repl_Agmt *ra);
int windows_replica_start_agreement(Replica *r, Repl_Agmt *ra);
-CSN *replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn);
+int32_t replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
int replica_get_attr(Slapi_PBlock *pb, const char *type, void *value);
/* mapping tree extensions manipulation */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 94507bf..5333398 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -3931,11 +3931,9 @@ windows_replica_start_agreement(Replica *r, Repl_Agmt *ra)
* A callback function registered as op->o_csngen_handler and
* called by backend ops to generate opcsn.
*/
-CSN *
-replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
+int32_t
+replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn)
{
- CSN *opcsn = NULL;
-
Replica *replica = replica_get_replica_for_op(pb);
if (NULL != replica) {
Slapi_Operation *op;
@@ -3946,17 +3944,26 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
CSNGen *gen = (CSNGen *)object_get_data(gen_obj);
if (NULL != gen) {
/* The new CSN should be greater than the base CSN */
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
- if (csn_compare(opcsn, basecsn) <= 0) {
- char opcsnstr[CSN_STRSIZE], basecsnstr[CSN_STRSIZE];
+ if (csngen_new_csn(gen, opcsn, PR_FALSE /* don't notify */) != CSN_SUCCESS) {
+ /* Failed to generate CSN we must abort */
+ object_release(gen_obj);
+ return -1;
+ }
+ if (csn_compare(*opcsn, basecsn) <= 0) {
+ char opcsnstr[CSN_STRSIZE];
+ char basecsnstr[CSN_STRSIZE];
char opcsn2str[CSN_STRSIZE];
- csn_as_string(opcsn, PR_FALSE, opcsnstr);
+ csn_as_string(*opcsn, PR_FALSE, opcsnstr);
csn_as_string(basecsn, PR_FALSE, basecsnstr);
- csn_free(&opcsn);
+ csn_free(opcsn);
csngen_adjust_time(gen, basecsn);
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
- csn_as_string(opcsn, PR_FALSE, opcsn2str);
+ if (csngen_new_csn(gen, opcsn, PR_FALSE) != CSN_SUCCESS) {
+ /* Failed to generate CSN we must abort */
+ object_release(gen_obj);
+ return -1;
+ }
+ csn_as_string(*opcsn, PR_FALSE, opcsn2str);
slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name,
"replica_generate_next_csn - "
"opcsn=%s <= basecsn=%s, adjusted opcsn=%s\n",
@@ -3966,14 +3973,14 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
* Insert opcsn into the csn pending list.
* This is the notify effect in csngen_new_csn().
*/
- assign_csn_callback(opcsn, (void *)replica);
+ assign_csn_callback(*opcsn, (void *)replica);
}
object_release(gen_obj);
}
}
}
- return opcsn;
+ return 0;
}
/*
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index d0d88bf..ee366c7 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -645,7 +645,13 @@ ldbm_back_add(Slapi_PBlock *pb)
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL);
+ if (entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_add",
+ "failed to generate add CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
entry_set_csn(e, opcsn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 873b5b0..fbcb573 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -464,7 +464,14 @@ replace_entry:
* by entry_assign_operation_csn() if the dn is in an
* updatable replica.
*/
- opcsn = entry_assign_operation_csn ( pb, e->ep_entry, NULL );
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_delete",
+ "failed to generate delete CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ retval = -1;
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
if (!is_fixup_operation) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index b0c477e..e9d7e87 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -598,12 +598,18 @@ ldbm_back_modify(Slapi_PBlock *pb)
goto error_return;
}
opcsn = operation_get_csn(operation);
- if (NULL == opcsn && operation->o_csngen_handler) {
+ if (opcsn == NULL && operation->o_csngen_handler) {
/*
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, NULL);
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modify",
+ "failed to generate modify CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn) {
entry_set_maxcsn(e->ep_entry, opcsn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 2669801..fde83c9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -543,7 +543,13 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL);
+ if (entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modrdn",
+ "failed to generate modrdn CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
entry_set_maxcsn(e->ep_entry, opcsn);
diff --git a/ldap/servers/slapd/csngen.c b/ldap/servers/slapd/csngen.c
index 68dbbda..b08d8b2 100644
--- a/ldap/servers/slapd/csngen.c
+++ b/ldap/servers/slapd/csngen.c
@@ -164,6 +164,7 @@ csngen_free(CSNGen **gen)
int
csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
{
+ struct timespec now = {0};
int rc = CSN_SUCCESS;
time_t cur_time;
int delta;
@@ -179,12 +180,25 @@ csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
return CSN_MEMORY_ERROR;
}
- slapi_rwlock_wrlock(gen->lock);
+ if ((rc = slapi_clock_gettime(&now)) != 0) {
+ /* Failed to get system time, we must abort */
+ slapi_log_err(SLAPI_LOG_ERR, "csngen_new_csn",
+ "Failed to get system time (%s)\n",
+ slapd_system_strerror(rc));
+ return CSN_TIME_ERROR;
+ }
+ cur_time = now.tv_sec;
- cur_time = slapi_current_utc_time();
+ slapi_rwlock_wrlock(gen->lock);
/* check if the time should be adjusted */
delta = cur_time - gen->state.sampled_time;
+ if (delta > _SEC_PER_DAY || delta < (-1 * _SEC_PER_DAY)) {
+ /* We had a jump larger than a day */
+ slapi_log_err(SLAPI_LOG_INFO, "csngen_new_csn",
+ "Detected large jump in CSN time. Delta: %d (current time: %ld vs previous time: %ld)\n",
+ delta, cur_time, gen->state.sampled_time);
+ }
if (delta > 0) {
rc = _csngen_adjust_local_time(gen, cur_time);
if (rc != CSN_SUCCESS) {
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 5d1d723..31bf65d 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -224,13 +224,12 @@ entry_add_rdn_csn(Slapi_Entry *e, const CSN *csn)
slapi_rdn_free(&rdn);
}
-CSN *
-entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry)
+int32_t
+entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn)
{
Slapi_Operation *op;
const CSN *basecsn = NULL;
const CSN *parententry_dncsn = NULL;
- CSN *opcsn = NULL;
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
@@ -252,14 +251,16 @@ entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parent
basecsn = parententry_dncsn;
}
}
- opcsn = op->o_csngen_handler(pb, basecsn);
+ if(op->o_csngen_handler(pb, basecsn, opcsn) != 0) {
+ return -1;
+ }
- if (NULL != opcsn) {
- operation_set_csn(op, opcsn);
+ if (*opcsn) {
+ operation_set_csn(op, *opcsn);
}
}
- return opcsn;
+ return 0;
}
/*
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 71ccdad..3ee541d 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1477,7 +1477,7 @@ struct op;
typedef void (*result_handler)(struct conn *, struct op *, int, char *, char *, int, struct berval **);
typedef int (*search_entry_handler)(Slapi_Backend *, struct conn *, struct op *, struct slapi_entry *);
typedef int (*search_referral_handler)(Slapi_Backend *, struct conn *, struct op *, struct berval **);
-typedef CSN *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn);
+typedef int32_t *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
typedef int (*replica_attr_handler)(Slapi_PBlock *pb, const char *type, void **value);
/*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 1fe4777..d59ab12 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6733,6 +6733,14 @@ int slapi_reslimit_get_integer_limit(Slapi_Connection *conn, int handle, int *li
time_t slapi_current_time(void) __attribute__((deprecated));
/**
+ * Get the system time and check for errors. Return
+ *
+ * \param tp - a timespec struct where the system time is set
+ * \return result code, upon success tp is set to the system time
+ */
+int32_t slapi_clock_gettime(struct timespec *tp);
+
+/**
* Returns the current system time as a hr clock relative to uptime
* This means the clock is not affected by timezones
* which can normally cause issues with timers. Additionally, this
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 0219912..b0647a0 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -233,7 +233,8 @@ enum
CSN_INVALID_PARAMETER, /* invalid function argument */
CSN_INVALID_FORMAT, /* invalid state format */
CSN_LDAP_ERROR, /* LDAP operation failed */
- CSN_NSPR_ERROR /* NSPR API failure */
+ CSN_NSPR_ERROR, /* NSPR API failure */
+ CSN_TIME_ERROR /* Error generating new CSN due to clock failure */
};
typedef struct csngen CSNGen;
@@ -326,7 +327,7 @@ int slapi_entries_diff(Slapi_Entry **old_entries, Slapi_Entry **new_entries, int
void set_attr_to_protected_list(char *attr, int flag);
/* entrywsi.c */
-CSN *entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry);
+int32_t entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn);
const CSN *entry_get_maxcsn(const Slapi_Entry *entry);
void entry_set_maxcsn(Slapi_Entry *entry, const CSN *csn);
const CSN *entry_get_dncsn(const Slapi_Entry *entry);
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index 8048a33..5455384 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -61,6 +61,25 @@ poll_current_time()
return 0;
}
+/*
+ * Check if the time function returns an error. If so return the errno
+ */
+int32_t
+slapi_clock_gettime(struct timespec *tp)
+{
+ int32_t rc = 0;
+
+ PR_ASSERT(tp && tp->tv_nsec == 0 && tp->tv_sec == 0);
+
+ if (clock_gettime(CLOCK_REALTIME, tp) != 0) {
+ rc = errno;
+ }
+
+ PR_ASSERT(rc == 0);
+
+ return rc;
+}
+
time_t
current_time(void)
{
@@ -69,7 +88,7 @@ current_time(void)
* but this should be removed in favour of the
* more accurately named slapi_current_utc_time
*/
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_REALTIME, &now);
return now.tv_sec;
}
@@ -83,7 +102,7 @@ slapi_current_time(void)
struct timespec
slapi_current_rel_time_hr(void)
{
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_MONOTONIC, &now);
return now;
}
@@ -91,7 +110,7 @@ slapi_current_rel_time_hr(void)
struct timespec
slapi_current_utc_time_hr(void)
{
- struct timespec ltnow;
+ struct timespec ltnow = {0};
clock_gettime(CLOCK_REALTIME, <now);
return ltnow;
}
@@ -99,7 +118,7 @@ slapi_current_utc_time_hr(void)
time_t
slapi_current_utc_time(void)
{
- struct timespec ltnow;
+ struct timespec ltnow = {0};
clock_gettime(CLOCK_REALTIME, <now);
return ltnow.tv_sec;
}
@@ -108,8 +127,8 @@ void
slapi_timestamp_utc_hr(char *buf, size_t bufsize)
{
PR_ASSERT(bufsize >= SLAPI_TIMESTAMP_BUFSIZE);
- struct timespec ltnow;
- struct tm utctm;
+ struct timespec ltnow = {0};
+ struct tm utctm = {0};
clock_gettime(CLOCK_REALTIME, <now);
gmtime_r(&(ltnow.tv_sec), &utctm);
strftime(buf, bufsize, "%Y%m%d%H%M%SZ", &utctm);
@@ -140,7 +159,7 @@ format_localTime_log(time_t t, int initsize __attribute__((unused)), char *buf,
{
long tz;
- struct tm *tmsp, tms;
+ struct tm *tmsp, tms = {0};
char tbuf[*bufsize];
char sign;
/* make sure our buffer will be big enough. Need at least 29 */
@@ -191,7 +210,7 @@ format_localTime_hr_log(time_t t, long nsec, int initsize __attribute__((unused)
{
long tz;
- struct tm *tmsp, tms;
+ struct tm *tmsp, tms = {0};
char tbuf[*bufsize];
char sign;
/* make sure our buffer will be big enough. Need at least 39 */
@@ -278,7 +297,7 @@ slapi_timespec_expire_check(struct timespec *expire)
if (expire->tv_sec == 0 && expire->tv_nsec == 0) {
return TIMER_CONTINUE;
}
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_MONOTONIC, &now);
if (now.tv_sec > expire->tv_sec ||
(expire->tv_sec == now.tv_sec && now.tv_sec > expire->tv_nsec)) {
@@ -293,7 +312,7 @@ format_localTime(time_t from)
in the syntax of a generalizedTime, except without the time zone. */
{
char *into;
- struct tm t;
+ struct tm t = {0};
localtime_r(&from, &t);
@@ -362,7 +381,7 @@ format_genTime(time_t from)
in the syntax of a generalizedTime. */
{
char *into;
- struct tm t;
+ struct tm t = {0};
gmtime_r(&from, &t);
into = slapi_ch_malloc(SLAPI_TIMESTAMP_BUFSIZE);
@@ -382,7 +401,7 @@ time_t
read_genTime(struct berval *from)
{
struct tm t = {0};
- time_t retTime;
+ time_t retTime = {0};
time_t diffsec = 0;
int i, gflag = 0, havesec = 0;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.2 updated: Issue 51095 - abort operation if CSN can not be generated
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.2
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.2 by this push:
new b709451 Issue 51095 - abort operation if CSN can not be generated
b709451 is described below
commit b7094517bc71438186951314adbd5be7ac4f45ba
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri May 22 10:42:11 2020 -0400
Issue 51095 - abort operation if CSN can not be generated
Bug Description: If we fail to get the system time then we were using an
uninitialized timespec struct which could lead to bizarre
times in CSN's.
Fix description: Check if the system time function fails, and if it does
then abort the update operation.
relates: https://pagure.io/389-ds-base/issue/51095
Reviewed by: firstyear & tbordaz(Thanks!!)
---
ldap/servers/plugins/replication/repl5.h | 2 +-
ldap/servers/plugins/replication/repl5_replica.c | 33 +++++++++++-------
ldap/servers/slapd/back-ldbm/ldbm_add.c | 8 ++++-
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 9 ++++-
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 10 ++++--
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 8 ++++-
ldap/servers/slapd/csngen.c | 18 ++++++++--
ldap/servers/slapd/entrywsi.c | 15 +++++----
ldap/servers/slapd/slap.h | 2 +-
ldap/servers/slapd/slapi-plugin.h | 8 +++++
ldap/servers/slapd/slapi-private.h | 5 +--
ldap/servers/slapd/time.c | 43 +++++++++++++++++-------
12 files changed, 118 insertions(+), 43 deletions(-)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 72b7089..6384717 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -776,7 +776,7 @@ void replica_disable_replication(Replica *r);
int replica_start_agreement(Replica *r, Repl_Agmt *ra);
int windows_replica_start_agreement(Replica *r, Repl_Agmt *ra);
-CSN *replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn);
+int32_t replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
int replica_get_attr(Slapi_PBlock *pb, const char *type, void *value);
/* mapping tree extensions manipulation */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 02caa88..f017823 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -3931,11 +3931,9 @@ windows_replica_start_agreement(Replica *r, Repl_Agmt *ra)
* A callback function registered as op->o_csngen_handler and
* called by backend ops to generate opcsn.
*/
-CSN *
-replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
+int32_t
+replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn)
{
- CSN *opcsn = NULL;
-
Replica *replica = replica_get_replica_for_op(pb);
if (NULL != replica) {
Slapi_Operation *op;
@@ -3946,17 +3944,26 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
CSNGen *gen = (CSNGen *)object_get_data(gen_obj);
if (NULL != gen) {
/* The new CSN should be greater than the base CSN */
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
- if (csn_compare(opcsn, basecsn) <= 0) {
- char opcsnstr[CSN_STRSIZE], basecsnstr[CSN_STRSIZE];
+ if (csngen_new_csn(gen, opcsn, PR_FALSE /* don't notify */) != CSN_SUCCESS) {
+ /* Failed to generate CSN we must abort */
+ object_release(gen_obj);
+ return -1;
+ }
+ if (csn_compare(*opcsn, basecsn) <= 0) {
+ char opcsnstr[CSN_STRSIZE];
+ char basecsnstr[CSN_STRSIZE];
char opcsn2str[CSN_STRSIZE];
- csn_as_string(opcsn, PR_FALSE, opcsnstr);
+ csn_as_string(*opcsn, PR_FALSE, opcsnstr);
csn_as_string(basecsn, PR_FALSE, basecsnstr);
- csn_free(&opcsn);
+ csn_free(opcsn);
csngen_adjust_time(gen, basecsn);
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
- csn_as_string(opcsn, PR_FALSE, opcsn2str);
+ if (csngen_new_csn(gen, opcsn, PR_FALSE) != CSN_SUCCESS) {
+ /* Failed to generate CSN we must abort */
+ object_release(gen_obj);
+ return -1;
+ }
+ csn_as_string(*opcsn, PR_FALSE, opcsn2str);
slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name,
"replica_generate_next_csn - "
"opcsn=%s <= basecsn=%s, adjusted opcsn=%s\n",
@@ -3966,14 +3973,14 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
* Insert opcsn into the csn pending list.
* This is the notify effect in csngen_new_csn().
*/
- assign_csn_callback(opcsn, (void *)replica);
+ assign_csn_callback(*opcsn, (void *)replica);
}
object_release(gen_obj);
}
}
}
- return opcsn;
+ return 0;
}
/*
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index d0d88bf..ee366c7 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -645,7 +645,13 @@ ldbm_back_add(Slapi_PBlock *pb)
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL);
+ if (entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_add",
+ "failed to generate add CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
entry_set_csn(e, opcsn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 873b5b0..fbcb573 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -464,7 +464,14 @@ replace_entry:
* by entry_assign_operation_csn() if the dn is in an
* updatable replica.
*/
- opcsn = entry_assign_operation_csn ( pb, e->ep_entry, NULL );
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_delete",
+ "failed to generate delete CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ retval = -1;
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
if (!is_fixup_operation) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index b0c477e..e9d7e87 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -598,12 +598,18 @@ ldbm_back_modify(Slapi_PBlock *pb)
goto error_return;
}
opcsn = operation_get_csn(operation);
- if (NULL == opcsn && operation->o_csngen_handler) {
+ if (opcsn == NULL && operation->o_csngen_handler) {
/*
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, NULL);
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modify",
+ "failed to generate modify CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn) {
entry_set_maxcsn(e->ep_entry, opcsn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 2669801..fde83c9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -543,7 +543,13 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL);
+ if (entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modrdn",
+ "failed to generate modrdn CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
entry_set_maxcsn(e->ep_entry, opcsn);
diff --git a/ldap/servers/slapd/csngen.c b/ldap/servers/slapd/csngen.c
index 68dbbda..b08d8b2 100644
--- a/ldap/servers/slapd/csngen.c
+++ b/ldap/servers/slapd/csngen.c
@@ -164,6 +164,7 @@ csngen_free(CSNGen **gen)
int
csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
{
+ struct timespec now = {0};
int rc = CSN_SUCCESS;
time_t cur_time;
int delta;
@@ -179,12 +180,25 @@ csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
return CSN_MEMORY_ERROR;
}
- slapi_rwlock_wrlock(gen->lock);
+ if ((rc = slapi_clock_gettime(&now)) != 0) {
+ /* Failed to get system time, we must abort */
+ slapi_log_err(SLAPI_LOG_ERR, "csngen_new_csn",
+ "Failed to get system time (%s)\n",
+ slapd_system_strerror(rc));
+ return CSN_TIME_ERROR;
+ }
+ cur_time = now.tv_sec;
- cur_time = slapi_current_utc_time();
+ slapi_rwlock_wrlock(gen->lock);
/* check if the time should be adjusted */
delta = cur_time - gen->state.sampled_time;
+ if (delta > _SEC_PER_DAY || delta < (-1 * _SEC_PER_DAY)) {
+ /* We had a jump larger than a day */
+ slapi_log_err(SLAPI_LOG_INFO, "csngen_new_csn",
+ "Detected large jump in CSN time. Delta: %d (current time: %ld vs previous time: %ld)\n",
+ delta, cur_time, gen->state.sampled_time);
+ }
if (delta > 0) {
rc = _csngen_adjust_local_time(gen, cur_time);
if (rc != CSN_SUCCESS) {
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 5d1d723..31bf65d 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -224,13 +224,12 @@ entry_add_rdn_csn(Slapi_Entry *e, const CSN *csn)
slapi_rdn_free(&rdn);
}
-CSN *
-entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry)
+int32_t
+entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn)
{
Slapi_Operation *op;
const CSN *basecsn = NULL;
const CSN *parententry_dncsn = NULL;
- CSN *opcsn = NULL;
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
@@ -252,14 +251,16 @@ entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parent
basecsn = parententry_dncsn;
}
}
- opcsn = op->o_csngen_handler(pb, basecsn);
+ if(op->o_csngen_handler(pb, basecsn, opcsn) != 0) {
+ return -1;
+ }
- if (NULL != opcsn) {
- operation_set_csn(op, opcsn);
+ if (*opcsn) {
+ operation_set_csn(op, *opcsn);
}
}
- return opcsn;
+ return 0;
}
/*
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index b3bf87d..7ef9460 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1475,7 +1475,7 @@ struct op;
typedef void (*result_handler)(struct conn *, struct op *, int, char *, char *, int, struct berval **);
typedef int (*search_entry_handler)(Slapi_Backend *, struct conn *, struct op *, struct slapi_entry *);
typedef int (*search_referral_handler)(Slapi_Backend *, struct conn *, struct op *, struct berval **);
-typedef CSN *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn);
+typedef int32_t *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
typedef int (*replica_attr_handler)(Slapi_PBlock *pb, const char *type, void **value);
/*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 00bf129..e6c6d0d 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6733,6 +6733,14 @@ int slapi_reslimit_get_integer_limit(Slapi_Connection *conn, int handle, int *li
time_t slapi_current_time(void) __attribute__((deprecated));
/**
+ * Get the system time and check for errors. Return
+ *
+ * \param tp - a timespec struct where the system time is set
+ * \return result code, upon success tp is set to the system time
+ */
+int32_t slapi_clock_gettime(struct timespec *tp);
+
+/**
* Returns the current system time as a hr clock relative to uptime
* This means the clock is not affected by timezones
* which can normally cause issues with timers. Additionally, this
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 0219912..b0647a0 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -233,7 +233,8 @@ enum
CSN_INVALID_PARAMETER, /* invalid function argument */
CSN_INVALID_FORMAT, /* invalid state format */
CSN_LDAP_ERROR, /* LDAP operation failed */
- CSN_NSPR_ERROR /* NSPR API failure */
+ CSN_NSPR_ERROR, /* NSPR API failure */
+ CSN_TIME_ERROR /* Error generating new CSN due to clock failure */
};
typedef struct csngen CSNGen;
@@ -326,7 +327,7 @@ int slapi_entries_diff(Slapi_Entry **old_entries, Slapi_Entry **new_entries, int
void set_attr_to_protected_list(char *attr, int flag);
/* entrywsi.c */
-CSN *entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry);
+int32_t entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn);
const CSN *entry_get_maxcsn(const Slapi_Entry *entry);
void entry_set_maxcsn(Slapi_Entry *entry, const CSN *csn);
const CSN *entry_get_dncsn(const Slapi_Entry *entry);
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index 8048a33..5455384 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -61,6 +61,25 @@ poll_current_time()
return 0;
}
+/*
+ * Check if the time function returns an error. If so return the errno
+ */
+int32_t
+slapi_clock_gettime(struct timespec *tp)
+{
+ int32_t rc = 0;
+
+ PR_ASSERT(tp && tp->tv_nsec == 0 && tp->tv_sec == 0);
+
+ if (clock_gettime(CLOCK_REALTIME, tp) != 0) {
+ rc = errno;
+ }
+
+ PR_ASSERT(rc == 0);
+
+ return rc;
+}
+
time_t
current_time(void)
{
@@ -69,7 +88,7 @@ current_time(void)
* but this should be removed in favour of the
* more accurately named slapi_current_utc_time
*/
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_REALTIME, &now);
return now.tv_sec;
}
@@ -83,7 +102,7 @@ slapi_current_time(void)
struct timespec
slapi_current_rel_time_hr(void)
{
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_MONOTONIC, &now);
return now;
}
@@ -91,7 +110,7 @@ slapi_current_rel_time_hr(void)
struct timespec
slapi_current_utc_time_hr(void)
{
- struct timespec ltnow;
+ struct timespec ltnow = {0};
clock_gettime(CLOCK_REALTIME, <now);
return ltnow;
}
@@ -99,7 +118,7 @@ slapi_current_utc_time_hr(void)
time_t
slapi_current_utc_time(void)
{
- struct timespec ltnow;
+ struct timespec ltnow = {0};
clock_gettime(CLOCK_REALTIME, <now);
return ltnow.tv_sec;
}
@@ -108,8 +127,8 @@ void
slapi_timestamp_utc_hr(char *buf, size_t bufsize)
{
PR_ASSERT(bufsize >= SLAPI_TIMESTAMP_BUFSIZE);
- struct timespec ltnow;
- struct tm utctm;
+ struct timespec ltnow = {0};
+ struct tm utctm = {0};
clock_gettime(CLOCK_REALTIME, <now);
gmtime_r(&(ltnow.tv_sec), &utctm);
strftime(buf, bufsize, "%Y%m%d%H%M%SZ", &utctm);
@@ -140,7 +159,7 @@ format_localTime_log(time_t t, int initsize __attribute__((unused)), char *buf,
{
long tz;
- struct tm *tmsp, tms;
+ struct tm *tmsp, tms = {0};
char tbuf[*bufsize];
char sign;
/* make sure our buffer will be big enough. Need at least 29 */
@@ -191,7 +210,7 @@ format_localTime_hr_log(time_t t, long nsec, int initsize __attribute__((unused)
{
long tz;
- struct tm *tmsp, tms;
+ struct tm *tmsp, tms = {0};
char tbuf[*bufsize];
char sign;
/* make sure our buffer will be big enough. Need at least 39 */
@@ -278,7 +297,7 @@ slapi_timespec_expire_check(struct timespec *expire)
if (expire->tv_sec == 0 && expire->tv_nsec == 0) {
return TIMER_CONTINUE;
}
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_MONOTONIC, &now);
if (now.tv_sec > expire->tv_sec ||
(expire->tv_sec == now.tv_sec && now.tv_sec > expire->tv_nsec)) {
@@ -293,7 +312,7 @@ format_localTime(time_t from)
in the syntax of a generalizedTime, except without the time zone. */
{
char *into;
- struct tm t;
+ struct tm t = {0};
localtime_r(&from, &t);
@@ -362,7 +381,7 @@ format_genTime(time_t from)
in the syntax of a generalizedTime. */
{
char *into;
- struct tm t;
+ struct tm t = {0};
gmtime_r(&from, &t);
into = slapi_ch_malloc(SLAPI_TIMESTAMP_BUFSIZE);
@@ -382,7 +401,7 @@ time_t
read_genTime(struct berval *from)
{
struct tm t = {0};
- time_t retTime;
+ time_t retTime = {0};
time_t diffsec = 0;
int i, gflag = 0, havesec = 0;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.3 updated: Issue 51095 - abort operation if CSN can not be generated
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.3
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.3 by this push:
new f8502d0 Issue 51095 - abort operation if CSN can not be generated
f8502d0 is described below
commit f8502d04a78d6c7b263a2983f43ad8c40a63abbe
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri May 22 10:42:11 2020 -0400
Issue 51095 - abort operation if CSN can not be generated
Bug Description: If we fail to get the system time then we were using an
uninitialized timespec struct which could lead to bizarre
times in CSN's.
Fix description: Check if the system time function fails, and if it does
then abort the update operation.
relates: https://pagure.io/389-ds-base/issue/51095
Reviewed by: firstyear & tbordaz(Thanks!!)
---
ldap/servers/plugins/replication/repl5.h | 2 +-
ldap/servers/plugins/replication/repl5_replica.c | 33 +++++++++++-------
ldap/servers/slapd/back-ldbm/ldbm_add.c | 8 ++++-
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 9 ++++-
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 10 ++++--
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 8 ++++-
ldap/servers/slapd/csngen.c | 18 ++++++++--
ldap/servers/slapd/entrywsi.c | 15 +++++----
ldap/servers/slapd/slap.h | 2 +-
ldap/servers/slapd/slapi-plugin.h | 8 +++++
ldap/servers/slapd/slapi-private.h | 5 +--
ldap/servers/slapd/time.c | 43 +++++++++++++++++-------
12 files changed, 118 insertions(+), 43 deletions(-)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 72b7089..6384717 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -776,7 +776,7 @@ void replica_disable_replication(Replica *r);
int replica_start_agreement(Replica *r, Repl_Agmt *ra);
int windows_replica_start_agreement(Replica *r, Repl_Agmt *ra);
-CSN *replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn);
+int32_t replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
int replica_get_attr(Slapi_PBlock *pb, const char *type, void *value);
/* mapping tree extensions manipulation */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 02caa88..f017823 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -3931,11 +3931,9 @@ windows_replica_start_agreement(Replica *r, Repl_Agmt *ra)
* A callback function registered as op->o_csngen_handler and
* called by backend ops to generate opcsn.
*/
-CSN *
-replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
+int32_t
+replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn)
{
- CSN *opcsn = NULL;
-
Replica *replica = replica_get_replica_for_op(pb);
if (NULL != replica) {
Slapi_Operation *op;
@@ -3946,17 +3944,26 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
CSNGen *gen = (CSNGen *)object_get_data(gen_obj);
if (NULL != gen) {
/* The new CSN should be greater than the base CSN */
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
- if (csn_compare(opcsn, basecsn) <= 0) {
- char opcsnstr[CSN_STRSIZE], basecsnstr[CSN_STRSIZE];
+ if (csngen_new_csn(gen, opcsn, PR_FALSE /* don't notify */) != CSN_SUCCESS) {
+ /* Failed to generate CSN we must abort */
+ object_release(gen_obj);
+ return -1;
+ }
+ if (csn_compare(*opcsn, basecsn) <= 0) {
+ char opcsnstr[CSN_STRSIZE];
+ char basecsnstr[CSN_STRSIZE];
char opcsn2str[CSN_STRSIZE];
- csn_as_string(opcsn, PR_FALSE, opcsnstr);
+ csn_as_string(*opcsn, PR_FALSE, opcsnstr);
csn_as_string(basecsn, PR_FALSE, basecsnstr);
- csn_free(&opcsn);
+ csn_free(opcsn);
csngen_adjust_time(gen, basecsn);
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
- csn_as_string(opcsn, PR_FALSE, opcsn2str);
+ if (csngen_new_csn(gen, opcsn, PR_FALSE) != CSN_SUCCESS) {
+ /* Failed to generate CSN we must abort */
+ object_release(gen_obj);
+ return -1;
+ }
+ csn_as_string(*opcsn, PR_FALSE, opcsn2str);
slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name,
"replica_generate_next_csn - "
"opcsn=%s <= basecsn=%s, adjusted opcsn=%s\n",
@@ -3966,14 +3973,14 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
* Insert opcsn into the csn pending list.
* This is the notify effect in csngen_new_csn().
*/
- assign_csn_callback(opcsn, (void *)replica);
+ assign_csn_callback(*opcsn, (void *)replica);
}
object_release(gen_obj);
}
}
}
- return opcsn;
+ return 0;
}
/*
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index d0d88bf..ee366c7 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -645,7 +645,13 @@ ldbm_back_add(Slapi_PBlock *pb)
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL);
+ if (entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_add",
+ "failed to generate add CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
entry_set_csn(e, opcsn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 873b5b0..fbcb573 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -464,7 +464,14 @@ replace_entry:
* by entry_assign_operation_csn() if the dn is in an
* updatable replica.
*/
- opcsn = entry_assign_operation_csn ( pb, e->ep_entry, NULL );
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_delete",
+ "failed to generate delete CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ retval = -1;
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
if (!is_fixup_operation) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index b0c477e..e9d7e87 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -598,12 +598,18 @@ ldbm_back_modify(Slapi_PBlock *pb)
goto error_return;
}
opcsn = operation_get_csn(operation);
- if (NULL == opcsn && operation->o_csngen_handler) {
+ if (opcsn == NULL && operation->o_csngen_handler) {
/*
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, NULL);
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modify",
+ "failed to generate modify CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn) {
entry_set_maxcsn(e->ep_entry, opcsn);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 2669801..fde83c9 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -543,7 +543,13 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
* Current op is a user request. Opcsn will be assigned
* if the dn is in an updatable replica.
*/
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL);
+ if (entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modrdn",
+ "failed to generate modrdn CSN for entry (%s), aborting operation\n",
+ slapi_entry_get_dn(e->ep_entry));
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
+ goto error_return;
+ }
}
if (opcsn != NULL) {
entry_set_maxcsn(e->ep_entry, opcsn);
diff --git a/ldap/servers/slapd/csngen.c b/ldap/servers/slapd/csngen.c
index 68dbbda..b08d8b2 100644
--- a/ldap/servers/slapd/csngen.c
+++ b/ldap/servers/slapd/csngen.c
@@ -164,6 +164,7 @@ csngen_free(CSNGen **gen)
int
csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
{
+ struct timespec now = {0};
int rc = CSN_SUCCESS;
time_t cur_time;
int delta;
@@ -179,12 +180,25 @@ csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
return CSN_MEMORY_ERROR;
}
- slapi_rwlock_wrlock(gen->lock);
+ if ((rc = slapi_clock_gettime(&now)) != 0) {
+ /* Failed to get system time, we must abort */
+ slapi_log_err(SLAPI_LOG_ERR, "csngen_new_csn",
+ "Failed to get system time (%s)\n",
+ slapd_system_strerror(rc));
+ return CSN_TIME_ERROR;
+ }
+ cur_time = now.tv_sec;
- cur_time = slapi_current_utc_time();
+ slapi_rwlock_wrlock(gen->lock);
/* check if the time should be adjusted */
delta = cur_time - gen->state.sampled_time;
+ if (delta > _SEC_PER_DAY || delta < (-1 * _SEC_PER_DAY)) {
+ /* We had a jump larger than a day */
+ slapi_log_err(SLAPI_LOG_INFO, "csngen_new_csn",
+ "Detected large jump in CSN time. Delta: %d (current time: %ld vs previous time: %ld)\n",
+ delta, cur_time, gen->state.sampled_time);
+ }
if (delta > 0) {
rc = _csngen_adjust_local_time(gen, cur_time);
if (rc != CSN_SUCCESS) {
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
index 5d1d723..31bf65d 100644
--- a/ldap/servers/slapd/entrywsi.c
+++ b/ldap/servers/slapd/entrywsi.c
@@ -224,13 +224,12 @@ entry_add_rdn_csn(Slapi_Entry *e, const CSN *csn)
slapi_rdn_free(&rdn);
}
-CSN *
-entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry)
+int32_t
+entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn)
{
Slapi_Operation *op;
const CSN *basecsn = NULL;
const CSN *parententry_dncsn = NULL;
- CSN *opcsn = NULL;
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
@@ -252,14 +251,16 @@ entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parent
basecsn = parententry_dncsn;
}
}
- opcsn = op->o_csngen_handler(pb, basecsn);
+ if(op->o_csngen_handler(pb, basecsn, opcsn) != 0) {
+ return -1;
+ }
- if (NULL != opcsn) {
- operation_set_csn(op, opcsn);
+ if (*opcsn) {
+ operation_set_csn(op, *opcsn);
}
}
- return opcsn;
+ return 0;
}
/*
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index a4cae78..cef8c78 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1480,7 +1480,7 @@ struct op;
typedef void (*result_handler)(struct conn *, struct op *, int, char *, char *, int, struct berval **);
typedef int (*search_entry_handler)(Slapi_Backend *, struct conn *, struct op *, struct slapi_entry *);
typedef int (*search_referral_handler)(Slapi_Backend *, struct conn *, struct op *, struct berval **);
-typedef CSN *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn);
+typedef int32_t *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
typedef int (*replica_attr_handler)(Slapi_PBlock *pb, const char *type, void **value);
/*
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index e41b6a8..d6a42af 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -6744,6 +6744,14 @@ int slapi_reslimit_get_integer_limit(Slapi_Connection *conn, int handle, int *li
time_t slapi_current_time(void) __attribute__((deprecated));
/**
+ * Get the system time and check for errors. Return
+ *
+ * \param tp - a timespec struct where the system time is set
+ * \return result code, upon success tp is set to the system time
+ */
+int32_t slapi_clock_gettime(struct timespec *tp);
+
+/**
* Returns the current system time as a hr clock relative to uptime
* This means the clock is not affected by timezones
* which can normally cause issues with timers. Additionally, this
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index d85ee43..c98c194 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -233,7 +233,8 @@ enum
CSN_INVALID_PARAMETER, /* invalid function argument */
CSN_INVALID_FORMAT, /* invalid state format */
CSN_LDAP_ERROR, /* LDAP operation failed */
- CSN_NSPR_ERROR /* NSPR API failure */
+ CSN_NSPR_ERROR, /* NSPR API failure */
+ CSN_TIME_ERROR /* Error generating new CSN due to clock failure */
};
typedef struct csngen CSNGen;
@@ -326,7 +327,7 @@ int slapi_entries_diff(Slapi_Entry **old_entries, Slapi_Entry **new_entries, int
void set_attr_to_protected_list(char *attr, int flag);
/* entrywsi.c */
-CSN *entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry);
+int32_t entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn);
const CSN *entry_get_maxcsn(const Slapi_Entry *entry);
void entry_set_maxcsn(Slapi_Entry *entry, const CSN *csn);
const CSN *entry_get_dncsn(const Slapi_Entry *entry);
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
index 8048a33..5455384 100644
--- a/ldap/servers/slapd/time.c
+++ b/ldap/servers/slapd/time.c
@@ -61,6 +61,25 @@ poll_current_time()
return 0;
}
+/*
+ * Check if the time function returns an error. If so return the errno
+ */
+int32_t
+slapi_clock_gettime(struct timespec *tp)
+{
+ int32_t rc = 0;
+
+ PR_ASSERT(tp && tp->tv_nsec == 0 && tp->tv_sec == 0);
+
+ if (clock_gettime(CLOCK_REALTIME, tp) != 0) {
+ rc = errno;
+ }
+
+ PR_ASSERT(rc == 0);
+
+ return rc;
+}
+
time_t
current_time(void)
{
@@ -69,7 +88,7 @@ current_time(void)
* but this should be removed in favour of the
* more accurately named slapi_current_utc_time
*/
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_REALTIME, &now);
return now.tv_sec;
}
@@ -83,7 +102,7 @@ slapi_current_time(void)
struct timespec
slapi_current_rel_time_hr(void)
{
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_MONOTONIC, &now);
return now;
}
@@ -91,7 +110,7 @@ slapi_current_rel_time_hr(void)
struct timespec
slapi_current_utc_time_hr(void)
{
- struct timespec ltnow;
+ struct timespec ltnow = {0};
clock_gettime(CLOCK_REALTIME, <now);
return ltnow;
}
@@ -99,7 +118,7 @@ slapi_current_utc_time_hr(void)
time_t
slapi_current_utc_time(void)
{
- struct timespec ltnow;
+ struct timespec ltnow = {0};
clock_gettime(CLOCK_REALTIME, <now);
return ltnow.tv_sec;
}
@@ -108,8 +127,8 @@ void
slapi_timestamp_utc_hr(char *buf, size_t bufsize)
{
PR_ASSERT(bufsize >= SLAPI_TIMESTAMP_BUFSIZE);
- struct timespec ltnow;
- struct tm utctm;
+ struct timespec ltnow = {0};
+ struct tm utctm = {0};
clock_gettime(CLOCK_REALTIME, <now);
gmtime_r(&(ltnow.tv_sec), &utctm);
strftime(buf, bufsize, "%Y%m%d%H%M%SZ", &utctm);
@@ -140,7 +159,7 @@ format_localTime_log(time_t t, int initsize __attribute__((unused)), char *buf,
{
long tz;
- struct tm *tmsp, tms;
+ struct tm *tmsp, tms = {0};
char tbuf[*bufsize];
char sign;
/* make sure our buffer will be big enough. Need at least 29 */
@@ -191,7 +210,7 @@ format_localTime_hr_log(time_t t, long nsec, int initsize __attribute__((unused)
{
long tz;
- struct tm *tmsp, tms;
+ struct tm *tmsp, tms = {0};
char tbuf[*bufsize];
char sign;
/* make sure our buffer will be big enough. Need at least 39 */
@@ -278,7 +297,7 @@ slapi_timespec_expire_check(struct timespec *expire)
if (expire->tv_sec == 0 && expire->tv_nsec == 0) {
return TIMER_CONTINUE;
}
- struct timespec now;
+ struct timespec now = {0};
clock_gettime(CLOCK_MONOTONIC, &now);
if (now.tv_sec > expire->tv_sec ||
(expire->tv_sec == now.tv_sec && now.tv_sec > expire->tv_nsec)) {
@@ -293,7 +312,7 @@ format_localTime(time_t from)
in the syntax of a generalizedTime, except without the time zone. */
{
char *into;
- struct tm t;
+ struct tm t = {0};
localtime_r(&from, &t);
@@ -362,7 +381,7 @@ format_genTime(time_t from)
in the syntax of a generalizedTime. */
{
char *into;
- struct tm t;
+ struct tm t = {0};
gmtime_r(&from, &t);
into = slapi_ch_malloc(SLAPI_TIMESTAMP_BUFSIZE);
@@ -382,7 +401,7 @@ time_t
read_genTime(struct berval *from)
{
struct tm t = {0};
- time_t retTime;
+ time_t retTime = {0};
time_t diffsec = 0;
int i, gflag = 0, havesec = 0;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months