From 3cf62d0429d31eaa9445b509328d84220c67d36e Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Thu, 17 May 2012 17:25:06 -0400 Subject: [PATCH] Ticket #321 - krbExtraData is being null modified and replicated on each ssh login Bug Description: When using fractional repl, if you update a attribute that is excluded, a modify op is still sent to the replicas. The update is basically empty, except we are still updating these attributes for no reason: modifiersname modifyTimestamp etc Fix Description: Added a new attribute to the replication agmt: nsds5ReplicaStripAttrs Add the attributes that you don't want replicated if the mods are "empty". Separate each attribute by a space: nsds5ReplicaStripAttrs: modifiersname modifytimestamp Side Note: Did a little optimization in repl5_strip_fractional_mods() as well. https://fedorahosted.org/389/ticket/321 Reviewed by: --- ldap/schema/01core389.ldif | 3 +- ldap/servers/plugins/replication/repl5.h | 2 + ldap/servers/plugins/replication/repl5_agmt.c | 25 ++++++++++ .../plugins/replication/repl5_protocol_util.c | 50 ++++++++++++++------ ldap/servers/plugins/replication/repl_globals.c | 1 + ldap/servers/slapd/charray.c | 5 ++ ldap/servers/slapd/slapi-plugin.h | 9 ++++ 7 files changed, 80 insertions(+), 15 deletions(-) diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif index b3df639..def693d 100644 --- a/ldap/schema/01core389.ldif +++ b/ldap/schema/01core389.ldif @@ -108,6 +108,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.808 NAME 'nsds5replicaLastInitEnd' DESC attributeTypes: ( 2.16.840.1.113730.3.1.809 NAME 'nsds5replicaLastInitStatus' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE NO-USER-MODIFICATION X-ORIGIN 'Netscape Directory Server' ) attributeTypes: ( 2.16.840.1.113730.3.1.1097 NAME 'nsds5replicaBusyWaitTime' DESC 'Netscape defined attribute type' EQUALITY integerMatch 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.1098 NAME 'nsds5replicaSessionPauseTime' DESC 'Netscape defined attribute type' EQUALITY integerMatch 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.2134 NAME 'nsds5ReplicaStripAttrs' 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.9999999 NAME 'nsds5debugreplicatimeout' 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.2064 NAME 'nsSaslMapRegexString' 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.2065 NAME 'nsSaslMapBaseDNTemplate' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' ) @@ -153,7 +154,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.110 NAME 'nsMappingTree' DESC 'Netscape d objectClasses: ( 2.16.840.1.113730.3.2.104 NAME 'nsContainer' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Netscape defined objectclass' SUP top MUST ( nsDS5ReplicaRoot $ nsDS5ReplicaId ) MAY (cn $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.113 NAME 'nsTombstone' DESC 'Netscape defined objectclass' SUP top MAY ( nsParentUniqueId $ nscpEntryDN ) X-ORIGIN 'Netscape Directory Server' ) -objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5replicaSessionPauseTime ) X-ORIGIN 'Netscape Directory Server' ) +objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5ReplicaStripAttrs $ nsds5replicaSessionPauseTime ) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.317 NAME 'nsSaslMapping' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSaslMapRegexString $ nsSaslMapBaseDNTemplate $ nsSaslMapFilterTemplate ) X-ORIGIN 'Netscape Directory Server' ) objectClasses: ( 2.16.840.1.113730.3.2.43 NAME 'nsSNMP' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSNMPEnabled ) MAY ( nsSNMPOrganization $ nsSNMPLocation $ nsSNMPContact $ nsSNMPDescription $ nsSNMPName $ nsSNMPMasterHost $ nsSNMPMasterPort ) X-ORIGIN 'Netscape Directory Server' ) diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h index 23d9753..d3feeb0 100644 --- a/ldap/servers/plugins/replication/repl5.h +++ b/ldap/servers/plugins/replication/repl5.h @@ -156,6 +156,7 @@ extern const char *type_nsds5ReplicaTimeout; extern const char *type_nsds5ReplicaBusyWaitTime; extern const char *type_nsds5ReplicaSessionPauseTime; extern const char *type_nsds5ReplicaEnabled; +extern const char *type_nsds5ReplicaStripAttrs; /* Attribute names for windows replication agreements */ extern const char *type_nsds7WindowsReplicaArea; @@ -356,6 +357,7 @@ void* agmt_get_connection( Repl_Agmt *ra); int agmt_has_protocol(Repl_Agmt *agmt); PRBool agmt_is_enabled(Repl_Agmt *ra); int agmt_set_enabled_from_entry(Repl_Agmt *ra, Slapi_Entry *e); +char **agmt_get_attrs_to_strip(Repl_Agmt *ra); typedef struct replica Replica; diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c index d194acc..4db7e13 100644 --- a/ldap/servers/plugins/replication/repl5_agmt.c +++ b/ldap/servers/plugins/replication/repl5_agmt.c @@ -138,6 +138,8 @@ typedef struct repl5agmt { void *priv; /* private data, used for windows-specific agreement data for sync agreements or for replication session plug-in private data for normal replication agreements */ + char **attrs_to_strip; /* for fractional replication, if a "mod" is empty, strip out these attributes: + * modifiersname, modifytimestamp, internalModifiersname, internalModifyTimestamp, etc */ int agreement_type; } repl5agmt; @@ -470,6 +472,16 @@ agmt_new_from_entry(Slapi_Entry *e) slapi_ch_array_free(denied_attrs); goto loser; } + /* + * Extract the attributes to strip for "empty" mods + */ + ra->attrs_to_strip = NULL; + tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaStripAttrs); + if (NULL != tmpstr) + { + ra->attrs_to_strip = slapi_str2charray_ext(tmpstr, " ", 0); + slapi_ch_free_string(&tmpstr); + } if (!agmt_is_valid(ra)) { @@ -575,6 +587,10 @@ agmt_delete(void **rap) windows_agreement_delete(ra); } + if(ra->attrs_to_strip){ + slapi_ch_array_free(ra->attrs_to_strip); + } + schedule_destroy(ra->schedule); slapi_ch_free((void **)&ra->long_name); slapi_ch_free((void **)rap); @@ -2540,3 +2556,12 @@ agmt_set_enabled_from_entry(Repl_Agmt *ra, Slapi_Entry *e){ return rc; } +char ** +agmt_get_attrs_to_strip(Repl_Agmt *ra) +{ + if(ra){ + return ra->attrs_to_strip; + } else { + return NULL; + } +} diff --git a/ldap/servers/plugins/replication/repl5_protocol_util.c b/ldap/servers/plugins/replication/repl5_protocol_util.c index 732d952..3327405 100644 --- a/ldap/servers/plugins/replication/repl5_protocol_util.c +++ b/ldap/servers/plugins/replication/repl5_protocol_util.c @@ -689,25 +689,25 @@ protocol_response2string (int response) int repl5_strip_fractional_mods(Repl_Agmt *agmt, LDAPMod ** mods) { - int retval = 0; - int i = 0; char **a = agmt_get_fractional_attrs(agmt); + char **attrs_to_strip; + int retval = 0; + int strip = 1; + int i, j, k; + if (a) { /* Iterate through the fractional attr list */ for ( i = 0; a[i] != NULL; i++ ) { - char *this_excluded_attr = a[i]; - int j = 0; - for ( j = 0; NULL != mods[ j ]; ) { - /* For each one iterate through the attrs in this mod list */ - /* For any that match, remove the mod */ - LDAPMod *this_mod = mods[j]; - if (0 == slapi_attr_type_cmp(this_mod->mod_type,this_excluded_attr,SLAPI_TYPE_CMP_SUBTYPE)) + /* + * Iterate through the attrs in this mod list. + * If any match the fractional attr then remove the mod. + */ + if (0 == slapi_attr_type_cmp(mods[j]->mod_type, a[i], SLAPI_TYPE_CMP_SUBTYPE)) { /* Move down all subsequent mods */ - int k = 0; for (k = j; mods[k+1] ; k++) { mods[k] = mods[k+1]; @@ -716,15 +716,37 @@ repl5_strip_fractional_mods(Repl_Agmt *agmt, LDAPMod ** mods) mods[k] = NULL; /* Adjust value of j, implicit in not incrementing it */ /* Free this mod */ - ber_bvecfree(this_mod->mod_bvalues); - slapi_ch_free((void **)&(this_mod->mod_type)); - slapi_ch_free((void **)&this_mod); - + ber_bvecfree(mods[j]->mod_bvalues); + slapi_ch_free((void **)&(mods[j]->mod_type)); + slapi_ch_free((void **)&mods[j]); } else { j++; } } } + /* + * Check if "all" the remaining mods are on attributes we want to strip from the update. + * If all the mods are on attrs_to_strip, then free them. + */ + if((attrs_to_strip = agmt_get_attrs_to_strip(agmt)) != NULL){ + for(j = 0; mods[j] != NULL; j++) + { + if(slapi_ch_array_utf8_inlist(attrs_to_strip, mods[j]->mod_type) == 0){ + /* at least one of the mods is "real", so don't strip anything */ + strip = 0; + break; + } + } + if(strip){ + /* free the remaining mods */ + for(j = 0; mods[j] != NULL; j++) + { + ber_bvecfree(mods[j]->mod_bvalues); + slapi_ch_free((void **)&(mods[j]->mod_type)); + slapi_ch_free((void **)&mods[j]); + } + } + } slapi_ch_array_free(a); } return retval; diff --git a/ldap/servers/plugins/replication/repl_globals.c b/ldap/servers/plugins/replication/repl_globals.c index d2d2318..9445394 100644 --- a/ldap/servers/plugins/replication/repl_globals.c +++ b/ldap/servers/plugins/replication/repl_globals.c @@ -127,6 +127,7 @@ const char *type_nsds5ReplicaTimeout = "nsds5ReplicaTimeout"; const char *type_nsds5ReplicaBusyWaitTime = "nsds5ReplicaBusyWaitTime"; const char *type_nsds5ReplicaSessionPauseTime = "nsds5ReplicaSessionPauseTime"; const char *type_nsds5ReplicaEnabled = "nsds5ReplicaEnabled"; +const char *type_nsds5ReplicaStripAttrs = "nsds5ReplicaStripAttrs"; /* windows sync specific attributes */ const char *type_nsds7WindowsReplicaArea = "nsds7WindowsReplicaSubtree"; diff --git a/ldap/servers/slapd/charray.c b/ldap/servers/slapd/charray.c index 1bb084f..7df9a08 100644 --- a/ldap/servers/slapd/charray.c +++ b/ldap/servers/slapd/charray.c @@ -296,6 +296,11 @@ charray_utf8_inlist( return( 0 ); } +int slapi_ch_array_utf8_inlist(char **a, char *s) +{ + return charray_utf8_inlist(a,s); +} + char ** charray_dup( char **a ) { diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index ec64974..823652a 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -5291,6 +5291,15 @@ char ** slapi_ch_array_dup( char **array ); */ void slapi_ch_array_add( char ***array, char *string ); +/** + * Find a string in an array of strings + * + * \param array The array of strings + * \param string The string to look for in the array + * \return NULL if there is no match + * \return 1 if there is a match + */ +int slapi_ch_array_utf8_inlist(char **array, char *string); /* * checking routines for allocating and freeing memory -- 1.7.1