From 20cb0c07d266923b03a6b1decc84c6ca166dd09a Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Jan 12 2015 21:46:18 +0000 Subject: Ticket 47617 - replication changelog trimming setting validation Bug Description: The changelog trimming interval setting is not validated. Multiple and invalid values were allowed. The new interval was also not taking effect until the old timeout completed. Fix Description: Add the config attribute to the core schema to addreess the multivalue issue. Added the setting validation checks, and notify the trimming thread when the interval is changed. Also applied these validatations to the changelog compact interval. https://fedorahosted.org/389/ticket/47617 Reviewed by: nhosoi(Thanks!) (cherry picked from commit f724b34b6c7ade56d3a66a58257b6b862c8fb221) --- diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif index a91efd8..223493d 100644 --- a/ldap/schema/01core389.ldif +++ b/ldap/schema/01core389.ldif @@ -161,6 +161,8 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2168 NAME 'schemaUpdateAttributeReject' attributeTypes: ( 2.16.840.1.113730.3.1.2307 NAME 'nsslapd-allow-hashed-passwords' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.2310 NAME 'nsds5ReplicaFlowControlWindow' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.2311 NAME 'nsds5ReplicaFlowControlPause' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) +attributeTypes: ( 2.16.840.1.113730.3.1.2313 NAME 'nsslapd-changelogtrim-interval' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) +attributeTypes: ( 2.16.840.1.113730.3.1.2314 NAME 'nsslapd-changelogcompactdb-interval' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) # # objectclasses # diff --git a/ldap/servers/plugins/replication/cl5.h b/ldap/servers/plugins/replication/cl5.h index 9666e9a..3c92193 100644 --- a/ldap/servers/plugins/replication/cl5.h +++ b/ldap/servers/plugins/replication/cl5.h @@ -56,8 +56,8 @@ typedef struct changelog5Config /* the changelog DB configuration parameters are defined as CL5DBConfig in cl5_api.h */ CL5DBConfig dbconfig; char *symmetricKey; - int compactInterval; - int trimInterval; + long compactInterval; + long trimInterval; }changelog5Config; /* initializes changelog*/ diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c index 42e52ae..2d9a0bd 100644 --- a/ldap/servers/plugins/replication/cl5_api.c +++ b/ldap/servers/plugins/replication/cl5_api.c @@ -1232,6 +1232,11 @@ cl5ConfigTrimming (int maxEntries, const char *maxAge, int compactInterval, int s_cl5Desc.dbTrim.trimInterval = trimInterval; } + /* The config was updated, notify the changelog trimming thread */ + PR_Lock(s_cl5Desc.clLock); + PR_NotifyCondVar(s_cl5Desc.clCvar); + PR_Unlock(s_cl5Desc.clLock); + PR_Unlock (s_cl5Desc.dbTrim.lock); _cl5RemoveThread (); diff --git a/ldap/servers/plugins/replication/cl5_api.h b/ldap/servers/plugins/replication/cl5_api.h index ba9eb32..eaf936f 100644 --- a/ldap/servers/plugins/replication/cl5_api.h +++ b/ldap/servers/plugins/replication/cl5_api.h @@ -47,6 +47,7 @@ #include "repl5.h" #include "repl5_prot_private.h" +#include #define BDB_IMPL "bdb" /* changelog type */ #define BDB_REPLPLUGIN "libreplication-plugin" /* This backend plugin */ diff --git a/ldap/servers/plugins/replication/cl5_config.c b/ldap/servers/plugins/replication/cl5_config.c index a3a0fb3..f4da738 100644 --- a/ldap/servers/plugins/replication/cl5_config.c +++ b/ldap/servers/plugins/replication/cl5_config.c @@ -398,20 +398,58 @@ changelog5_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entr } else if ( strcasecmp ( config_attr, CONFIG_CHANGELOG_COMPACTDB_ATTRIBUTE ) == 0 ) { - if (config_attr_value && config_attr_value[0] != '\0') - { - config.compactInterval = atoi (config_attr_value); - } - else - { - config.compactInterval = 0; - } + char *endp = NULL; + long value; + + errno = 0; + + if (config_attr_value && config_attr_value[0] != '\0') + { + value = strtol(config_attr_value, &endp, 10); + + if (*endp != '\0' || errno == ERANGE || value < 0 ) { + if (returntext) + { + PR_snprintf ( returntext, SLAPI_DSE_RETURNTEXT_SIZE, + "%s: invalid value \"%s\", %s must range from 0 to %lld", + CONFIG_CHANGELOG_COMPACTDB_ATTRIBUTE, config_attr_value, + CONFIG_CHANGELOG_COMPACTDB_ATTRIBUTE, + (long long int)LONG_MAX ); + *returncode = LDAP_UNWILLING_TO_PERFORM; + goto done; + } + config.compactInterval = value; + } + } + else + { + config.compactInterval = 0; + } } else if ( strcasecmp ( config_attr, CONFIG_CHANGELOG_TRIM_ATTRIBUTE ) == 0 ) { + char *endp = NULL; + long value; + + errno = 0; + if (config_attr_value && config_attr_value[0] != '\0') { - config.trimInterval = atoi (config_attr_value); + value = strtol(config_attr_value, &endp, 10); + + if (*endp != '\0' || errno == ERANGE || value < 0 ) { + if (returntext) + { + PR_snprintf ( returntext, SLAPI_DSE_RETURNTEXT_SIZE, + "%s: invalid value \"%s\", %s must range from 0 to %lld", + CONFIG_CHANGELOG_TRIM_ATTRIBUTE, config_attr_value, + CONFIG_CHANGELOG_TRIM_ATTRIBUTE, + (long long int)LONG_MAX ); + *returncode = LDAP_UNWILLING_TO_PERFORM; + goto done; + } + config.trimInterval = value; + } } else { @@ -761,7 +799,24 @@ static void changelog5_extract_config(Slapi_Entry* entry, changelog5Config *conf arg = slapi_entry_attr_get_charptr(entry,CONFIG_CHANGELOG_COMPACTDB_ATTRIBUTE); if (arg) { - config->compactInterval = atoi (arg); + char *endp = NULL; + long value; + + errno = 0; + + if (arg) + { + value = strtol(arg, &endp, 10); + if (*endp != '\0' || errno == ERANGE || value < 0 ) { + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, + "changelog5_extract_config: %s: invalid value \"%s\", using default value (%d)\n", + CONFIG_CHANGELOG_COMPACTDB_ATTRIBUTE, arg, + CHANGELOGDB_COMPACT_INTERVAL ); + config->compactInterval = CHANGELOGDB_COMPACT_INTERVAL; + } else { + config->compactInterval = value; + } + } slapi_ch_free_string(&arg); } else @@ -771,7 +826,24 @@ static void changelog5_extract_config(Slapi_Entry* entry, changelog5Config *conf arg = slapi_entry_attr_get_charptr(entry, CONFIG_CHANGELOG_TRIM_ATTRIBUTE); if (arg) { - config->trimInterval = atoi (arg); + char *endp = NULL; + long value; + + errno = 0; + + if (arg) + { + value = strtol(arg, &endp, 10); + if (*endp != '\0' || errno == ERANGE || value < 0 ) { + slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name_cl, + "changelog5_extract_config: %s: invalid value \"%s\", using default value (%d)\n", + CONFIG_CHANGELOG_TRIM_ATTRIBUTE, arg, + CHANGELOGDB_TRIM_INTERVAL ); + config->trimInterval = CHANGELOGDB_TRIM_INTERVAL; + } else { + config->trimInterval = value; + } + } slapi_ch_free_string(&arg); } else