|
|
de47d7 |
From d9f1be15663f673588e2746e5a97f8ee2c92769f Mon Sep 17 00:00:00 2001
|
|
|
de47d7 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
de47d7 |
Date: Fri, 22 May 2020 10:42:11 -0400
|
|
|
de47d7 |
Subject: [PATCH] Issue 51095 - abort operation if CSN can not be generated
|
|
|
de47d7 |
|
|
|
de47d7 |
Bug Description: If we fail to get the system time then we were using an
|
|
|
de47d7 |
uninitialized timespec struct which could lead to bizarre
|
|
|
de47d7 |
times in CSN's.
|
|
|
de47d7 |
|
|
|
de47d7 |
Fix description: Check if the system time function fails, and if it does
|
|
|
de47d7 |
then abort the update operation.
|
|
|
de47d7 |
|
|
|
de47d7 |
relates: https://pagure.io/389-ds-base/issue/51095
|
|
|
de47d7 |
|
|
|
de47d7 |
Reviewed by: firstyear & tbordaz(Thanks!!)
|
|
|
de47d7 |
---
|
|
|
de47d7 |
ldap/servers/plugins/replication/repl5.h | 2 +-
|
|
|
de47d7 |
.../plugins/replication/repl5_replica.c | 29 ++++++++-----
|
|
|
de47d7 |
ldap/servers/slapd/back-ldbm/ldbm_add.c | 8 +++-
|
|
|
de47d7 |
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 9 +++-
|
|
|
de47d7 |
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 10 ++++-
|
|
|
de47d7 |
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 8 +++-
|
|
|
de47d7 |
ldap/servers/slapd/csngen.c | 18 +++++++-
|
|
|
de47d7 |
ldap/servers/slapd/entrywsi.c | 15 ++++---
|
|
|
de47d7 |
ldap/servers/slapd/slap.h | 2 +-
|
|
|
de47d7 |
ldap/servers/slapd/slapi-plugin.h | 8 ++++
|
|
|
de47d7 |
ldap/servers/slapd/slapi-private.h | 5 ++-
|
|
|
de47d7 |
ldap/servers/slapd/time.c | 43 +++++++++++++------
|
|
|
de47d7 |
12 files changed, 116 insertions(+), 41 deletions(-)
|
|
|
de47d7 |
|
|
|
de47d7 |
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
|
|
|
de47d7 |
index b06c6fbf4..bdc59422a 100644
|
|
|
de47d7 |
--- a/ldap/servers/plugins/replication/repl5.h
|
|
|
de47d7 |
+++ b/ldap/servers/plugins/replication/repl5.h
|
|
|
de47d7 |
@@ -775,7 +775,7 @@ void replica_disable_replication(Replica *r, Object *r_obj);
|
|
|
de47d7 |
int replica_start_agreement(Replica *r, Repl_Agmt *ra);
|
|
|
de47d7 |
int windows_replica_start_agreement(Replica *r, Repl_Agmt *ra);
|
|
|
de47d7 |
|
|
|
de47d7 |
-CSN *replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn);
|
|
|
de47d7 |
+int32_t replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
|
|
|
de47d7 |
int replica_get_attr(Slapi_PBlock *pb, const char *type, void *value);
|
|
|
de47d7 |
|
|
|
de47d7 |
/* mapping tree extensions manipulation */
|
|
|
de47d7 |
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
|
|
de47d7 |
index cdbcde39a..c1b3ed73c 100644
|
|
|
de47d7 |
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
|
|
de47d7 |
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
|
|
de47d7 |
@@ -3976,10 +3976,9 @@ windows_replica_start_agreement(Replica *r, Repl_Agmt *ra)
|
|
|
de47d7 |
* A callback function registered as op->o_csngen_handler and
|
|
|
de47d7 |
* called by backend ops to generate opcsn.
|
|
|
de47d7 |
*/
|
|
|
de47d7 |
-CSN *
|
|
|
de47d7 |
-replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
|
|
|
de47d7 |
+int32_t
|
|
|
de47d7 |
+replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
- CSN *opcsn = NULL;
|
|
|
de47d7 |
Object *replica_obj;
|
|
|
de47d7 |
|
|
|
de47d7 |
replica_obj = replica_get_replica_for_op(pb);
|
|
|
de47d7 |
@@ -3994,17 +3993,25 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
|
|
|
de47d7 |
CSNGen *gen = (CSNGen *)object_get_data(gen_obj);
|
|
|
de47d7 |
if (NULL != gen) {
|
|
|
de47d7 |
/* The new CSN should be greater than the base CSN */
|
|
|
de47d7 |
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
|
|
|
de47d7 |
- if (csn_compare(opcsn, basecsn) <= 0) {
|
|
|
de47d7 |
+ if (csngen_new_csn(gen, opcsn, PR_FALSE /* don't notify */) != CSN_SUCCESS) {
|
|
|
de47d7 |
+ /* Failed to generate CSN we must abort */
|
|
|
de47d7 |
+ object_release(gen_obj);
|
|
|
de47d7 |
+ return -1;
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
+ if (csn_compare(*opcsn, basecsn) <= 0) {
|
|
|
de47d7 |
char opcsnstr[CSN_STRSIZE], basecsnstr[CSN_STRSIZE];
|
|
|
de47d7 |
char opcsn2str[CSN_STRSIZE];
|
|
|
de47d7 |
|
|
|
de47d7 |
- csn_as_string(opcsn, PR_FALSE, opcsnstr);
|
|
|
de47d7 |
+ csn_as_string(*opcsn, PR_FALSE, opcsnstr);
|
|
|
de47d7 |
csn_as_string(basecsn, PR_FALSE, basecsnstr);
|
|
|
de47d7 |
- csn_free(&opcsn);
|
|
|
de47d7 |
+ csn_free(opcsn);
|
|
|
de47d7 |
csngen_adjust_time(gen, basecsn);
|
|
|
de47d7 |
- csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
|
|
|
de47d7 |
- csn_as_string(opcsn, PR_FALSE, opcsn2str);
|
|
|
de47d7 |
+ if (csngen_new_csn(gen, opcsn, PR_FALSE /* don't notify */) != CSN_SUCCESS) {
|
|
|
de47d7 |
+ /* Failed to generate CSN we must abort */
|
|
|
de47d7 |
+ object_release(gen_obj);
|
|
|
de47d7 |
+ return -1;
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
+ csn_as_string(*opcsn, PR_FALSE, opcsn2str);
|
|
|
de47d7 |
slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name,
|
|
|
de47d7 |
"replica_generate_next_csn - "
|
|
|
de47d7 |
"opcsn=%s <= basecsn=%s, adjusted opcsn=%s\n",
|
|
|
de47d7 |
@@ -4014,7 +4021,7 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
|
|
|
de47d7 |
* Insert opcsn into the csn pending list.
|
|
|
de47d7 |
* This is the notify effect in csngen_new_csn().
|
|
|
de47d7 |
*/
|
|
|
de47d7 |
- assign_csn_callback(opcsn, (void *)replica);
|
|
|
de47d7 |
+ assign_csn_callback(*opcsn, (void *)replica);
|
|
|
de47d7 |
}
|
|
|
de47d7 |
object_release(gen_obj);
|
|
|
de47d7 |
}
|
|
|
de47d7 |
@@ -4023,7 +4030,7 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
|
|
|
de47d7 |
object_release(replica_obj);
|
|
|
de47d7 |
}
|
|
|
de47d7 |
|
|
|
de47d7 |
- return opcsn;
|
|
|
de47d7 |
+ return 0;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
|
|
|
de47d7 |
/*
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
|
|
de47d7 |
index 264f0ceea..09bfb8468 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
|
|
|
de47d7 |
@@ -644,7 +644,13 @@ ldbm_back_add(Slapi_PBlock *pb)
|
|
|
de47d7 |
* Current op is a user request. Opcsn will be assigned
|
|
|
de47d7 |
* if the dn is in an updatable replica.
|
|
|
de47d7 |
*/
|
|
|
de47d7 |
- opcsn = entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL);
|
|
|
de47d7 |
+ if (entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
|
|
|
de47d7 |
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_add",
|
|
|
de47d7 |
+ "failed to generate add CSN for entry (%s), aborting operation\n",
|
|
|
de47d7 |
+ slapi_entry_get_dn(e));
|
|
|
de47d7 |
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
|
|
|
de47d7 |
+ goto error_return;
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
}
|
|
|
de47d7 |
if (opcsn != NULL) {
|
|
|
de47d7 |
entry_set_csn(e, opcsn);
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
|
|
de47d7 |
index 1ad846447..6c4229049 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
|
|
|
de47d7 |
@@ -463,7 +463,14 @@ replace_entry:
|
|
|
de47d7 |
* by entry_assign_operation_csn() if the dn is in an
|
|
|
de47d7 |
* updatable replica.
|
|
|
de47d7 |
*/
|
|
|
de47d7 |
- opcsn = entry_assign_operation_csn ( pb, e->ep_entry, NULL );
|
|
|
de47d7 |
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
|
|
|
de47d7 |
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_delete",
|
|
|
de47d7 |
+ "failed to generate delete CSN for entry (%s), aborting operation\n",
|
|
|
de47d7 |
+ slapi_entry_get_dn(e->ep_entry));
|
|
|
de47d7 |
+ retval = -1;
|
|
|
de47d7 |
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
|
|
|
de47d7 |
+ goto error_return;
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
}
|
|
|
de47d7 |
if (opcsn != NULL) {
|
|
|
de47d7 |
if (!is_fixup_operation) {
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
|
|
|
de47d7 |
index b0c477e3f..e9d7e87e3 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
|
|
|
de47d7 |
@@ -598,12 +598,18 @@ ldbm_back_modify(Slapi_PBlock *pb)
|
|
|
de47d7 |
goto error_return;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
opcsn = operation_get_csn(operation);
|
|
|
de47d7 |
- if (NULL == opcsn && operation->o_csngen_handler) {
|
|
|
de47d7 |
+ if (opcsn == NULL && operation->o_csngen_handler) {
|
|
|
de47d7 |
/*
|
|
|
de47d7 |
* Current op is a user request. Opcsn will be assigned
|
|
|
de47d7 |
* if the dn is in an updatable replica.
|
|
|
de47d7 |
*/
|
|
|
de47d7 |
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, NULL);
|
|
|
de47d7 |
+ if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
|
|
|
de47d7 |
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modify",
|
|
|
de47d7 |
+ "failed to generate modify CSN for entry (%s), aborting operation\n",
|
|
|
de47d7 |
+ slapi_entry_get_dn(e->ep_entry));
|
|
|
de47d7 |
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
|
|
|
de47d7 |
+ goto error_return;
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
}
|
|
|
de47d7 |
if (opcsn) {
|
|
|
de47d7 |
entry_set_maxcsn(e->ep_entry, opcsn);
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
|
|
de47d7 |
index 26698012a..fde83c99f 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
|
|
|
de47d7 |
@@ -543,7 +543,13 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
|
|
|
de47d7 |
* Current op is a user request. Opcsn will be assigned
|
|
|
de47d7 |
* if the dn is in an updatable replica.
|
|
|
de47d7 |
*/
|
|
|
de47d7 |
- opcsn = entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL);
|
|
|
de47d7 |
+ if (entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
|
|
|
de47d7 |
+ slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modrdn",
|
|
|
de47d7 |
+ "failed to generate modrdn CSN for entry (%s), aborting operation\n",
|
|
|
de47d7 |
+ slapi_entry_get_dn(e->ep_entry));
|
|
|
de47d7 |
+ ldap_result_code = LDAP_OPERATIONS_ERROR;
|
|
|
de47d7 |
+ goto error_return;
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
}
|
|
|
de47d7 |
if (opcsn != NULL) {
|
|
|
de47d7 |
entry_set_maxcsn(e->ep_entry, opcsn);
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/csngen.c b/ldap/servers/slapd/csngen.c
|
|
|
de47d7 |
index 68dbbda8e..b08d8b25c 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/csngen.c
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/csngen.c
|
|
|
de47d7 |
@@ -164,6 +164,7 @@ csngen_free(CSNGen **gen)
|
|
|
de47d7 |
int
|
|
|
de47d7 |
csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
+ struct timespec now = {0};
|
|
|
de47d7 |
int rc = CSN_SUCCESS;
|
|
|
de47d7 |
time_t cur_time;
|
|
|
de47d7 |
int delta;
|
|
|
de47d7 |
@@ -179,12 +180,25 @@ csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
|
|
|
de47d7 |
return CSN_MEMORY_ERROR;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
|
|
|
de47d7 |
- slapi_rwlock_wrlock(gen->lock);
|
|
|
de47d7 |
+ if ((rc = slapi_clock_gettime(&now)) != 0) {
|
|
|
de47d7 |
+ /* Failed to get system time, we must abort */
|
|
|
de47d7 |
+ slapi_log_err(SLAPI_LOG_ERR, "csngen_new_csn",
|
|
|
de47d7 |
+ "Failed to get system time (%s)\n",
|
|
|
de47d7 |
+ slapd_system_strerror(rc));
|
|
|
de47d7 |
+ return CSN_TIME_ERROR;
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
+ cur_time = now.tv_sec;
|
|
|
de47d7 |
|
|
|
de47d7 |
- cur_time = slapi_current_utc_time();
|
|
|
de47d7 |
+ slapi_rwlock_wrlock(gen->lock);
|
|
|
de47d7 |
|
|
|
de47d7 |
/* check if the time should be adjusted */
|
|
|
de47d7 |
delta = cur_time - gen->state.sampled_time;
|
|
|
de47d7 |
+ if (delta > _SEC_PER_DAY || delta < (-1 * _SEC_PER_DAY)) {
|
|
|
de47d7 |
+ /* We had a jump larger than a day */
|
|
|
de47d7 |
+ slapi_log_err(SLAPI_LOG_INFO, "csngen_new_csn",
|
|
|
de47d7 |
+ "Detected large jump in CSN time. Delta: %d (current time: %ld vs previous time: %ld)\n",
|
|
|
de47d7 |
+ delta, cur_time, gen->state.sampled_time);
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
if (delta > 0) {
|
|
|
de47d7 |
rc = _csngen_adjust_local_time(gen, cur_time);
|
|
|
de47d7 |
if (rc != CSN_SUCCESS) {
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
|
|
|
de47d7 |
index 080eb15aa..12ac5678a 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/entrywsi.c
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/entrywsi.c
|
|
|
de47d7 |
@@ -224,13 +224,12 @@ entry_add_rdn_csn(Slapi_Entry *e, const CSN *csn)
|
|
|
de47d7 |
slapi_rdn_free(&rdn;;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
|
|
|
de47d7 |
-CSN *
|
|
|
de47d7 |
-entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry)
|
|
|
de47d7 |
+int32_t
|
|
|
de47d7 |
+entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
Slapi_Operation *op;
|
|
|
de47d7 |
const CSN *basecsn = NULL;
|
|
|
de47d7 |
const CSN *parententry_dncsn = NULL;
|
|
|
de47d7 |
- CSN *opcsn = NULL;
|
|
|
de47d7 |
|
|
|
de47d7 |
slapi_pblock_get(pb, SLAPI_OPERATION, &op);
|
|
|
de47d7 |
|
|
|
de47d7 |
@@ -252,14 +251,16 @@ entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parent
|
|
|
de47d7 |
basecsn = parententry_dncsn;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
}
|
|
|
de47d7 |
- opcsn = op->o_csngen_handler(pb, basecsn);
|
|
|
de47d7 |
+ if(op->o_csngen_handler(pb, basecsn, opcsn) != 0) {
|
|
|
de47d7 |
+ return -1;
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
|
|
|
de47d7 |
- if (NULL != opcsn) {
|
|
|
de47d7 |
- operation_set_csn(op, opcsn);
|
|
|
de47d7 |
+ if (*opcsn) {
|
|
|
de47d7 |
+ operation_set_csn(op, *opcsn);
|
|
|
de47d7 |
}
|
|
|
de47d7 |
}
|
|
|
de47d7 |
|
|
|
de47d7 |
- return opcsn;
|
|
|
de47d7 |
+ return 0;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
|
|
|
de47d7 |
/*
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
|
|
de47d7 |
index 4c53d43dc..1d0a9cbeb 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/slap.h
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/slap.h
|
|
|
de47d7 |
@@ -1464,7 +1464,7 @@ struct op;
|
|
|
de47d7 |
typedef void (*result_handler)(struct conn *, struct op *, int, char *, char *, int, struct berval **);
|
|
|
de47d7 |
typedef int (*search_entry_handler)(Slapi_Backend *, struct conn *, struct op *, struct slapi_entry *);
|
|
|
de47d7 |
typedef int (*search_referral_handler)(Slapi_Backend *, struct conn *, struct op *, struct berval **);
|
|
|
de47d7 |
-typedef CSN *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn);
|
|
|
de47d7 |
+typedef int32_t *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
|
|
|
de47d7 |
typedef int (*replica_attr_handler)(Slapi_PBlock *pb, const char *type, void **value);
|
|
|
de47d7 |
|
|
|
de47d7 |
/*
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
|
|
de47d7 |
index 865d83b9b..ea9bcf87b 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/slapi-plugin.h
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/slapi-plugin.h
|
|
|
de47d7 |
@@ -6772,6 +6772,14 @@ int slapi_reslimit_get_integer_limit(Slapi_Connection *conn, int handle, int *li
|
|
|
de47d7 |
*/
|
|
|
de47d7 |
time_t slapi_current_time(void) __attribute__((deprecated));
|
|
|
de47d7 |
|
|
|
de47d7 |
+/**
|
|
|
de47d7 |
+ * Get the system time and check for errors. Return
|
|
|
de47d7 |
+ *
|
|
|
de47d7 |
+ * \param tp - a timespec struct where the system time is set
|
|
|
de47d7 |
+ * \return result code, upon success tp is set to the system time
|
|
|
de47d7 |
+ */
|
|
|
de47d7 |
+int32_t slapi_clock_gettime(struct timespec *tp);
|
|
|
de47d7 |
+
|
|
|
de47d7 |
/**
|
|
|
de47d7 |
* Returns the current system time as a hr clock relative to uptime
|
|
|
de47d7 |
* This means the clock is not affected by timezones
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
|
|
|
de47d7 |
index d676486a8..f37cfcd41 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/slapi-private.h
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/slapi-private.h
|
|
|
de47d7 |
@@ -227,7 +227,8 @@ enum
|
|
|
de47d7 |
CSN_INVALID_PARAMETER, /* invalid function argument */
|
|
|
de47d7 |
CSN_INVALID_FORMAT, /* invalid state format */
|
|
|
de47d7 |
CSN_LDAP_ERROR, /* LDAP operation failed */
|
|
|
de47d7 |
- CSN_NSPR_ERROR /* NSPR API failure */
|
|
|
de47d7 |
+ CSN_NSPR_ERROR, /* NSPR API failure */
|
|
|
de47d7 |
+ CSN_TIME_ERROR /* Error generating new CSN due to clock failure */
|
|
|
de47d7 |
};
|
|
|
de47d7 |
|
|
|
de47d7 |
typedef struct csngen CSNGen;
|
|
|
de47d7 |
@@ -320,7 +321,7 @@ int slapi_entries_diff(Slapi_Entry **old_entries, Slapi_Entry **new_entries, int
|
|
|
de47d7 |
void set_attr_to_protected_list(char *attr, int flag);
|
|
|
de47d7 |
|
|
|
de47d7 |
/* entrywsi.c */
|
|
|
de47d7 |
-CSN *entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry);
|
|
|
de47d7 |
+int32_t entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn);
|
|
|
de47d7 |
const CSN *entry_get_maxcsn(const Slapi_Entry *entry);
|
|
|
de47d7 |
void entry_set_maxcsn(Slapi_Entry *entry, const CSN *csn);
|
|
|
de47d7 |
const CSN *entry_get_dncsn(const Slapi_Entry *entry);
|
|
|
de47d7 |
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
|
|
|
de47d7 |
index 8048a3359..545538404 100644
|
|
|
de47d7 |
--- a/ldap/servers/slapd/time.c
|
|
|
de47d7 |
+++ b/ldap/servers/slapd/time.c
|
|
|
de47d7 |
@@ -61,6 +61,25 @@ poll_current_time()
|
|
|
de47d7 |
return 0;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
|
|
|
de47d7 |
+/*
|
|
|
de47d7 |
+ * Check if the time function returns an error. If so return the errno
|
|
|
de47d7 |
+ */
|
|
|
de47d7 |
+int32_t
|
|
|
de47d7 |
+slapi_clock_gettime(struct timespec *tp)
|
|
|
de47d7 |
+{
|
|
|
de47d7 |
+ int32_t rc = 0;
|
|
|
de47d7 |
+
|
|
|
de47d7 |
+ PR_ASSERT(tp && tp->tv_nsec == 0 && tp->tv_sec == 0);
|
|
|
de47d7 |
+
|
|
|
de47d7 |
+ if (clock_gettime(CLOCK_REALTIME, tp) != 0) {
|
|
|
de47d7 |
+ rc = errno;
|
|
|
de47d7 |
+ }
|
|
|
de47d7 |
+
|
|
|
de47d7 |
+ PR_ASSERT(rc == 0);
|
|
|
de47d7 |
+
|
|
|
de47d7 |
+ return rc;
|
|
|
de47d7 |
+}
|
|
|
de47d7 |
+
|
|
|
de47d7 |
time_t
|
|
|
de47d7 |
current_time(void)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
@@ -69,7 +88,7 @@ current_time(void)
|
|
|
de47d7 |
* but this should be removed in favour of the
|
|
|
de47d7 |
* more accurately named slapi_current_utc_time
|
|
|
de47d7 |
*/
|
|
|
de47d7 |
- struct timespec now;
|
|
|
de47d7 |
+ struct timespec now = {0};
|
|
|
de47d7 |
clock_gettime(CLOCK_REALTIME, &now;;
|
|
|
de47d7 |
return now.tv_sec;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
@@ -83,7 +102,7 @@ slapi_current_time(void)
|
|
|
de47d7 |
struct timespec
|
|
|
de47d7 |
slapi_current_rel_time_hr(void)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
- struct timespec now;
|
|
|
de47d7 |
+ struct timespec now = {0};
|
|
|
de47d7 |
clock_gettime(CLOCK_MONOTONIC, &now;;
|
|
|
de47d7 |
return now;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
@@ -91,7 +110,7 @@ slapi_current_rel_time_hr(void)
|
|
|
de47d7 |
struct timespec
|
|
|
de47d7 |
slapi_current_utc_time_hr(void)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
- struct timespec ltnow;
|
|
|
de47d7 |
+ struct timespec ltnow = {0};
|
|
|
de47d7 |
clock_gettime(CLOCK_REALTIME, <now);
|
|
|
de47d7 |
return ltnow;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
@@ -99,7 +118,7 @@ slapi_current_utc_time_hr(void)
|
|
|
de47d7 |
time_t
|
|
|
de47d7 |
slapi_current_utc_time(void)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
- struct timespec ltnow;
|
|
|
de47d7 |
+ struct timespec ltnow = {0};
|
|
|
de47d7 |
clock_gettime(CLOCK_REALTIME, <now);
|
|
|
de47d7 |
return ltnow.tv_sec;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
@@ -108,8 +127,8 @@ void
|
|
|
de47d7 |
slapi_timestamp_utc_hr(char *buf, size_t bufsize)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
PR_ASSERT(bufsize >= SLAPI_TIMESTAMP_BUFSIZE);
|
|
|
de47d7 |
- struct timespec ltnow;
|
|
|
de47d7 |
- struct tm utctm;
|
|
|
de47d7 |
+ struct timespec ltnow = {0};
|
|
|
de47d7 |
+ struct tm utctm = {0};
|
|
|
de47d7 |
clock_gettime(CLOCK_REALTIME, <now);
|
|
|
de47d7 |
gmtime_r(&(ltnow.tv_sec), &utctm);
|
|
|
de47d7 |
strftime(buf, bufsize, "%Y%m%d%H%M%SZ", &utctm);
|
|
|
de47d7 |
@@ -140,7 +159,7 @@ format_localTime_log(time_t t, int initsize __attribute__((unused)), char *buf,
|
|
|
de47d7 |
{
|
|
|
de47d7 |
|
|
|
de47d7 |
long tz;
|
|
|
de47d7 |
- struct tm *tmsp, tms;
|
|
|
de47d7 |
+ struct tm *tmsp, tms = {0};
|
|
|
de47d7 |
char tbuf[*bufsize];
|
|
|
de47d7 |
char sign;
|
|
|
de47d7 |
/* make sure our buffer will be big enough. Need at least 29 */
|
|
|
de47d7 |
@@ -191,7 +210,7 @@ format_localTime_hr_log(time_t t, long nsec, int initsize __attribute__((unused)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
|
|
|
de47d7 |
long tz;
|
|
|
de47d7 |
- struct tm *tmsp, tms;
|
|
|
de47d7 |
+ struct tm *tmsp, tms = {0};
|
|
|
de47d7 |
char tbuf[*bufsize];
|
|
|
de47d7 |
char sign;
|
|
|
de47d7 |
/* make sure our buffer will be big enough. Need at least 39 */
|
|
|
de47d7 |
@@ -278,7 +297,7 @@ slapi_timespec_expire_check(struct timespec *expire)
|
|
|
de47d7 |
if (expire->tv_sec == 0 && expire->tv_nsec == 0) {
|
|
|
de47d7 |
return TIMER_CONTINUE;
|
|
|
de47d7 |
}
|
|
|
de47d7 |
- struct timespec now;
|
|
|
de47d7 |
+ struct timespec now = {0};
|
|
|
de47d7 |
clock_gettime(CLOCK_MONOTONIC, &now;;
|
|
|
de47d7 |
if (now.tv_sec > expire->tv_sec ||
|
|
|
de47d7 |
(expire->tv_sec == now.tv_sec && now.tv_sec > expire->tv_nsec)) {
|
|
|
de47d7 |
@@ -293,7 +312,7 @@ format_localTime(time_t from)
|
|
|
de47d7 |
in the syntax of a generalizedTime, except without the time zone. */
|
|
|
de47d7 |
{
|
|
|
de47d7 |
char *into;
|
|
|
de47d7 |
- struct tm t;
|
|
|
de47d7 |
+ struct tm t = {0};
|
|
|
de47d7 |
|
|
|
de47d7 |
localtime_r(&from, &t);
|
|
|
de47d7 |
|
|
|
de47d7 |
@@ -362,7 +381,7 @@ format_genTime(time_t from)
|
|
|
de47d7 |
in the syntax of a generalizedTime. */
|
|
|
de47d7 |
{
|
|
|
de47d7 |
char *into;
|
|
|
de47d7 |
- struct tm t;
|
|
|
de47d7 |
+ struct tm t = {0};
|
|
|
de47d7 |
|
|
|
de47d7 |
gmtime_r(&from, &t);
|
|
|
de47d7 |
into = slapi_ch_malloc(SLAPI_TIMESTAMP_BUFSIZE);
|
|
|
de47d7 |
@@ -382,7 +401,7 @@ time_t
|
|
|
de47d7 |
read_genTime(struct berval *from)
|
|
|
de47d7 |
{
|
|
|
de47d7 |
struct tm t = {0};
|
|
|
de47d7 |
- time_t retTime;
|
|
|
de47d7 |
+ time_t retTime = {0};
|
|
|
de47d7 |
time_t diffsec = 0;
|
|
|
de47d7 |
int i, gflag = 0, havesec = 0;
|
|
|
de47d7 |
|
|
|
de47d7 |
--
|
|
|
de47d7 |
2.26.2
|
|
|
de47d7 |
|