andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 1ba64caa57b31c9ba4a376da6244d5ff43b63ee2 Mon Sep 17 00:00:00 2001
dc8c34
From: Noriko Hosoi <nhosoi@redhat.com>
dc8c34
Date: Fri, 24 Jan 2014 18:12:32 -0800
dc8c34
Subject: [PATCH 208/225] Ticket #47649 - Server hangs in cos_cache when adding
dc8c34
 a user entry
dc8c34
dc8c34
Bug description: cos_dn_defs_cb reads cosDefinition and sets up the cos
dc8c34
Definition part of cos cache.  In the function, when processing
dc8c34
cosAttribute, cosTargetTree and cosTemlpateDn are missing, it sets the
dc8c34
parent dn of the cos definition dn.  This parent setting is needed only
dc8c34
when the 2 attributes are completely missing from the cos definition.
dc8c34
But if the attributes are located below cosAttribute (see the Example
dc8c34
cos definition), in addition to "cn=cosTemplates,ou=people,dc=example,
dc8c34
dc=com", the parent of "cn=generatePostalCode,ou=People,dc=example,dc=com"
dc8c34
is added to the cos cache as cosTemplateDn.
dc8c34
  Example cos definition:
dc8c34
    dn: cn=generatePostalCode,ou=People,dc=example,dc=com
dc8c34
    description: generate postalCode attr based on location
dc8c34
    objectClass: top
dc8c34
    objectClass: ldapsubentry
dc8c34
    objectClass: cossuperdefinition
dc8c34
    objectClass: cosClassicDefinition
dc8c34
    cosAttribute: postalCode
dc8c34
    costemplatedn: cn=cosTemplates,ou=people,dc=example,dc=com
dc8c34
    cosSpecifier: l
dc8c34
    cn: generatePostalCode
dc8c34
The mistakenly added cosTemplatedDn makes adding an entry under ou=People
dc8c34
notify recreating the cos cache.  The notification needs to be outside of
dc8c34
backend transaction since it causes a deadlock with the cos_cache_wait_
dc8c34
on_change thread which cannot read the DB due to the transaction but holds
dc8c34
the lock that the notifier thread is waiting for.
dc8c34
dc8c34
Fix description: The parent of the cos definition dn is set to the
dc8c34
cosTargetTree and the cosTemlpateDn, only when the attributes are
dc8c34
completely missing.
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/47649
dc8c34
dc8c34
Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
dc8c34
(cherry picked from commit 1e52401d3abd0377f55676f4a1508a02aaa7f955)
dc8c34
(cherry picked from commit 01c0794cde7eb91a1a4e477a0286533df4a4ae38)
dc8c34
dc8c34
(cherry picked from commit 1ebad4bd50fb1483998a32b5d3e232e89aeda0f7)
dc8c34
(cherry picked from commit 8f39dd5f9f32645177417d32fb9c987a35ddd33e)
dc8c34
---
dc8c34
 ldap/servers/plugins/cos/cos_cache.c | 82 +++++++++++++++++++++---------------
dc8c34
 1 file changed, 48 insertions(+), 34 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
dc8c34
index 895154d..1ff02f9 100644
dc8c34
--- a/ldap/servers/plugins/cos/cos_cache.c
dc8c34
+++ b/ldap/servers/plugins/cos/cos_cache.c
dc8c34
@@ -767,7 +767,8 @@ struct dn_defs_info {
dc8c34
  * if a particular attempt to add a definition fails: info.ret gets set to
dc8c34
  * zero only if we succed to add a def.
dc8c34
 */
dc8c34
-static int 	cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
dc8c34
+static int 
dc8c34
+cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
dc8c34
 {
dc8c34
 	struct dn_defs_info *info;
dc8c34
 	cosAttrValue **pSneakyVal = 0;
dc8c34
@@ -917,31 +918,10 @@ static int 	cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
dc8c34
 					                      dnVals[valIndex]->bv_val);
dc8c34
 				}
dc8c34
 
dc8c34
-				if(!pCosTargetTree)
dc8c34
-				{
dc8c34
-					/* get the parent of the definition */
dc8c34
-					char *orig = slapi_dn_parent(pDn->val);
dc8c34
-					Slapi_DN *psdn = slapi_sdn_new_dn_byval(orig);
dc8c34
-					char *parent = (char *)slapi_sdn_get_dn(psdn);
dc8c34
-					if (!parent) {
dc8c34
-						parent = (char *)slapi_sdn_get_udn(psdn);
dc8c34
-						LDAPDebug(LDAP_DEBUG_ANY, 
dc8c34
-						  "cos_cache_build_definition_list: "
dc8c34
-						  "failed to normalize parent dn %s. "
dc8c34
-						  "Adding the pre normalized dn.\n", 
dc8c34
-						  parent, 0, 0);
dc8c34
-					}
dc8c34
-					cos_cache_add_attrval(&pCosTargetTree, parent);
dc8c34
-					if (!pCosTemplateDn) {
dc8c34
-						cos_cache_add_attrval(&pCosTemplateDn, parent);
dc8c34
-					}
dc8c34
-					slapi_sdn_free(&psdn);
dc8c34
-				}
dc8c34
-				
dc8c34
 				slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle,
dc8c34
 				                        dnVals[valIndex]->bv_val, NULL, NULL);
dc8c34
 			} /* if(attrType is cosAttribute) */
dc8c34
-										
dc8c34
+
dc8c34
 			/*
dc8c34
 			 * Add the attributetype to the appropriate
dc8c34
 			 * list.
dc8c34
@@ -953,6 +933,47 @@ static int 	cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
dc8c34
 		ber_bvecfree( dnVals );
dc8c34
 		dnVals = NULL;
dc8c34
 	} while(!slapi_entry_next_attr(e, dnAttr, &dnAttr));
dc8c34
+
dc8c34
+	if (pCosAttribute && (!pCosTargetTree || !pCosTemplateDn)) {
dc8c34
+		/* get the parent of the definition */
dc8c34
+		char *orig = slapi_dn_parent(pDn->val);
dc8c34
+		char *parent = NULL;
dc8c34
+		if (orig) {
dc8c34
+			parent = slapi_create_dn_string("%s", orig);
dc8c34
+			if (!parent) {
dc8c34
+				parent = orig;
dc8c34
+				LDAPDebug1Arg(LDAP_DEBUG_ANY, 
dc8c34
+				              "cos_dn_defs_cb: "
dc8c34
+				              "failed to normalize parent dn %s. "
dc8c34
+				              "Adding the pre normalized dn.\n", 
dc8c34
+				              parent);
dc8c34
+			}
dc8c34
+			if (!pCosTargetTree) {
dc8c34
+				cos_cache_add_attrval(&pCosTargetTree, parent);
dc8c34
+			}
dc8c34
+			if (!pCosTemplateDn) {
dc8c34
+				cos_cache_add_attrval(&pCosTemplateDn, parent);
dc8c34
+			}
dc8c34
+			if (parent != orig) {
dc8c34
+				slapi_ch_free_string(&parent);
dc8c34
+			}
dc8c34
+			slapi_ch_free_string(&orig);
dc8c34
+		} else {
dc8c34
+			LDAPDebug1Arg(LDAP_DEBUG_ANY, 
dc8c34
+			              "cos_dn_defs_cb: "
dc8c34
+			              "failed to get parent dn of cos definition %s.\n",
dc8c34
+			              pDn->val);
dc8c34
+			if (!pCosTemplateDn) {
dc8c34
+				if (!pCosTargetTree) {
dc8c34
+					LDAPDebug0Args(LDAP_DEBUG_ANY, "cosTargetTree and cosTemplateDn are not set.\n");
dc8c34
+				} else {
dc8c34
+					LDAPDebug0Args(LDAP_DEBUG_ANY, "cosTemplateDn is not set.\n");
dc8c34
+				}
dc8c34
+			} else if (!pCosTargetTree) {
dc8c34
+				LDAPDebug0Args(LDAP_DEBUG_ANY, "cosTargetTree is not set.\n");
dc8c34
+			}
dc8c34
+		}
dc8c34
+	}
dc8c34
 	
dc8c34
 	/*
dc8c34
 	determine the type of class of service scheme 
dc8c34
@@ -991,9 +1012,7 @@ static int 	cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
dc8c34
 	*/
dc8c34
 	
dc8c34
 	/* these must exist */
dc8c34
-	if(		pDn &&
dc8c34
-		pObjectclass && 
dc8c34
-		
dc8c34
+	if(pDn && pObjectclass && 
dc8c34
 		(
dc8c34
 		(cosType == COSTYPE_CLASSIC &&
dc8c34
 		pCosTemplateDn && 
dc8c34
@@ -3623,14 +3642,9 @@ static int cos_cache_entry_is_cos_related( Slapi_Entry *e) {
dc8c34
 			{
dc8c34
 				pObj = (char*)slapi_value_get_string(val);
dc8c34
 
dc8c34
-				/*
dc8c34
-				 * objectclasses are ascii--maybe strcasecmp() is faster than
dc8c34
-				 * slapi_utf8casecmp()
dc8c34
-				*/
dc8c34
-				if(	!strcasecmp(pObj, "cosdefinition") ||
dc8c34
-					!strcasecmp(pObj, "cossuperdefinition") ||
dc8c34
-					!strcasecmp(pObj, "costemplate")
dc8c34
-					)
dc8c34
+				if(!strcasecmp(pObj, "cosdefinition") ||
dc8c34
+				   !strcasecmp(pObj, "cossuperdefinition") ||
dc8c34
+				   !strcasecmp(pObj, "costemplate"))
dc8c34
 				{
dc8c34
 					rc = 1;
dc8c34
 				}
dc8c34
-- 
dc8c34
1.8.1.4
dc8c34