[Fedora-directory-commits] ldapserver/ldap/servers/slapd vattr.c, 1.7, 1.8

Noriko Hosoi (nhosoi) fedora-directory-commits at redhat.com
Thu Nov 1 20:24:09 UTC 2007


Author: nhosoi

Update of /cvs/dirsec/ldapserver/ldap/servers/slapd
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv9625

Modified Files:
	vattr.c 
Log Message:
Resolves: #193724
Summary: "nested" filtered roles result in deadlock
Description: Function slapi_vattr_values_get_sp used to use the context 
allocated on the stack.	Changed it to call vattr_context_new to set the 
locally created pblock (local_pb).  The pblock is used to pass the context 
loop info as the stack gets deeper to prevent the stack overflow.  At the 
end of this function slapi_vattr_values_get_sp, slapi_pblock_destroy is 
called if the context is local (use_local_ctx).	The function cleans up 
pb_vattr_context internally.



Index: vattr.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/vattr.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- vattr.c	12 Oct 2007 18:03:42 -0000	1.7
+++ vattr.c	1 Nov 2007 20:24:07 -0000	1.8
@@ -630,163 +630,162 @@
 */
 SLAPI_DEPRECATED int
 slapi_vattr_values_get_sp(vattr_context *c,
-							/* Entry we're interested in */ Slapi_Entry *e,
-							/* attr type name */ char *type,
-							/* pointer to result set */ Slapi_ValueSet** results,
-							int *type_name_disposition,
-							char** actual_type_name, int flags,
-							int *buffer_flags) 
-{
-
-  PRBool use_local_ctx=PR_FALSE;
-  vattr_context ctx;
-	int rc = 0;
-	int sp_bit = 0; /* Set if an SP supplied an answer */
-	vattr_sp_handle_list *list = NULL;
-
-	vattr_get_thang my_get = {0};
-
-	if (c != NULL) {
-	  rc = vattr_context_grok(&c);
-	  if (0 != rc) {
-		if(!vattr_context_is_loop_msg_displayed(&c))
-		{
-			/* Print a handy error log message */
-			LDAPDebug(LDAP_DEBUG_ANY,"Detected virtual attribute loop in get on entry %s, attribute %s\n", slapi_entry_get_dn_const(e), type, 0);
-			vattr_context_set_loop_msg_displayed(&c);
-		}
-	    return rc;
-	  }
-	} else {
-	  use_local_ctx=PR_TRUE;
-	  ctx.vattr_context_loop_count=1;
-	  ctx.error_displayed = 0;
-	}
-
-	/* For attributes which are in the entry, we just need to get to the Slapi_Attr structure and yank out the slapi_value_set 
-	   structure. We either return a pointer directly to it, or we copy it, depending upon whether the caller asked us to try to 
-	   avoid copying.
-	*/
-
-	/* First grok the entry, and remember what we saw. This call does no more than walk down the entry attribute list, do some string compares and copy pointers. */
-	vattr_helper_get_entry_conts(e,type, &my_get);
-	/* Having done that, we now consult the attribute map to find service providers who are interested */
-	/* Look for attribute in the map */
-	if(!(flags & SLAPI_REALATTRS_ONLY))
-	{
-		list = vattr_map_sp_getlist(type);
-		if (list) {
-			vattr_sp_handle *current_handle = NULL;
-			void *hint = NULL;
-			/* first lets consult the cache to save work */
-			int cache_status;
-						
-			cache_status =
-				slapi_entry_vattrcache_find_values_and_type(e, type,
-															results,
-															actual_type_name);															
-			switch(cache_status)
-			{
-				case SLAPI_ENTRY_VATTR_RESOLVED_EXISTS: /* cached vattr */
-				{
-					sp_bit = 1;					
-
-					/* Complete analysis of type matching */
-					if ( 0 == slapi_attr_type_cmp( type , *actual_type_name, SLAPI_TYPE_CMP_EXACT) )
-					{
-						*type_name_disposition = SLAPI_VIRTUALATTRS_TYPE_NAME_MATCHED_EXACTLY_OR_ALIAS;
-					} else {
-						*type_name_disposition = SLAPI_VIRTUALATTRS_TYPE_NAME_MATCHED_SUBTYPE;
-					}
-
-					break;
-				}
-
-				case SLAPI_ENTRY_VATTR_RESOLVED_ABSENT: /* does not exist */
-					break; /* look in entry */
-
-				case SLAPI_ENTRY_VATTR_NOT_RESOLVED: /* not resolved */
-				default: /* any other result, resolve */
-				{
-					for (current_handle = vattr_map_sp_first(list,&hint); current_handle; current_handle = vattr_map_sp_next(current_handle,&hint))
-					{
-						if (use_local_ctx)
-						{
-							rc = vattr_call_sp_get_value(current_handle,&ctx,e,&my_get,type,results,type_name_disposition,actual_type_name,flags,buffer_flags, hint);
-						}
-						else
-						{
-							/* call this SP */
-							rc = vattr_call_sp_get_value(current_handle,c,e,&my_get,type,results,type_name_disposition,actual_type_name,flags,buffer_flags, hint);
-						}
-
-						if (0 == rc)
-						{
-							sp_bit = 1;
-							break;
-						}
-					}
-
-					if(!sp_bit)
-					{
-						/* clean up, we have failed and must now examine the
-						 * entry itself
-						 * But first lets cache the no result
-						 * Creates the type (if necessary).
-						*/
-						slapi_entry_vattrcache_merge_sv(e, type, NULL );
-
-					}
-					else
-					{
-						/*
-						 * we need to cache the virtual attribute
-						 * creates the type (if necessary) and dups
-						 * results.
-						*/
-						slapi_entry_vattrcache_merge_sv(e, *actual_type_name,
-														*results );
-					}
-
-					break;
-				}
-			}
-		}
-	}
-	/* If no SP supplied the answer, take it from the entry */
-	if (!sp_bit && !(flags & SLAPI_VIRTUALATTRS_ONLY)) 
-	{
-		rc = 0; /* reset return code (cause an sp must have failed) */
-		*type_name_disposition = my_get.get_name_disposition;
-
-		if (my_get.get_present) {
-			if (flags & SLAPI_VIRTUALATTRS_REQUEST_POINTERS) {
-				*results = my_get.get_present_values;
-				*actual_type_name = my_get.get_type_name;
-			} else {
-				*results = valueset_dup(my_get.get_present_values);
-				if (NULL == *results) {
-					rc = ENOMEM;
-				} else {
-					*actual_type_name = slapi_ch_strdup(my_get.get_type_name);
-					if (NULL == *actual_type_name) {
-						rc = ENOMEM;
-					}
-				}
-			}
-			if (flags & SLAPI_VIRTUALATTRS_REQUEST_POINTERS) {
-					*buffer_flags = SLAPI_VIRTUALATTRS_RETURNED_POINTERS;
-			} else {
-				*buffer_flags = SLAPI_VIRTUALATTRS_RETURNED_COPIES;
-			}
-		} else {
-			rc = SLAPI_VIRTUALATTRS_NOT_FOUND;
-		}
-	}
-	if (!use_local_ctx) {
-	  vattr_context_ungrok(&c);
-	}
-	return rc;
+                          /* Entry we're interested in */ Slapi_Entry *e,
+                          /* attr type name */ char *type,
+                          /* pointer to result set */ Slapi_ValueSet** results,
+                          int *type_name_disposition,
+                          char** actual_type_name, int flags,
+                          int *buffer_flags) 
+{
+  PRBool use_local_ctx = PR_FALSE;
+  Slapi_PBlock *local_pb = NULL;
+  vattr_context *ctx = NULL;
+  int rc = 0;
+  int sp_bit = 0; /* Set if an SP supplied an answer */
+  vattr_sp_handle_list *list = NULL;
+
+  vattr_get_thang my_get = {0};
+
+  if (c != NULL) {
+    rc = vattr_context_grok(&c);
+    if (0 != rc) {
+      if(!vattr_context_is_loop_msg_displayed(&c))
+      {
+        /* Print a handy error log message */
+        LDAPDebug(LDAP_DEBUG_ANY,
+          "Detected virtual attribute loop in get on entry %s, attribute %s\n",
+          slapi_entry_get_dn_const(e), type, 0);
+        vattr_context_set_loop_msg_displayed(&c);
+      }
+      return rc;
+    }
+    ctx = c;
+  } else {
+    use_local_ctx = PR_TRUE;
+    local_pb = slapi_pblock_new();
+    ctx = vattr_context_new( local_pb );
+    ctx->vattr_context_loop_count = 1;
+    ctx->error_displayed = 0;
+  }
+
+  /* For attributes which are in the entry, we just need to get to the Slapi_Attr structure and yank out the slapi_value_set 
+     structure. We either return a pointer directly to it, or we copy it, depending upon whether the caller asked us to try to 
+     avoid copying.
+  */
+
+  /* First grok the entry, and remember what we saw. This call does no more than walk down the entry attribute list, do some string compares and copy pointers. */
+  vattr_helper_get_entry_conts(e,type, &my_get);
+  /* Having done that, we now consult the attribute map to find service providers who are interested */
+  /* Look for attribute in the map */
+  if(!(flags & SLAPI_REALATTRS_ONLY))
+  {
+    list = vattr_map_sp_getlist(type);
+    if (list) {
+      vattr_sp_handle *current_handle = NULL;
+      void *hint = NULL;
+      /* first lets consult the cache to save work */
+      int cache_status;
+            
+      cache_status =
+        slapi_entry_vattrcache_find_values_and_type(e, type,
+                              results,
+                              actual_type_name);                              
+      switch(cache_status)
+      {
+        case SLAPI_ENTRY_VATTR_RESOLVED_EXISTS: /* cached vattr */
+        {
+          sp_bit = 1;          
+
+          /* Complete analysis of type matching */
+          if ( 0 == slapi_attr_type_cmp( type , *actual_type_name, SLAPI_TYPE_CMP_EXACT) )
+          {
+            *type_name_disposition = SLAPI_VIRTUALATTRS_TYPE_NAME_MATCHED_EXACTLY_OR_ALIAS;
+          } else {
+            *type_name_disposition = SLAPI_VIRTUALATTRS_TYPE_NAME_MATCHED_SUBTYPE;
+          }
+
+          break;
+        }
+
+        case SLAPI_ENTRY_VATTR_RESOLVED_ABSENT: /* does not exist */
+          break; /* look in entry */
+
+        case SLAPI_ENTRY_VATTR_NOT_RESOLVED: /* not resolved */
+        default: /* any other result, resolve */
+        {
+          for (current_handle = vattr_map_sp_first(list,&hint); current_handle; current_handle = vattr_map_sp_next(current_handle,&hint))
+          {
+            rc = vattr_call_sp_get_value(current_handle,ctx,e,&my_get,type,results,type_name_disposition,actual_type_name,flags,buffer_flags, hint);
+            if (0 == rc)
+            {
+              sp_bit = 1;
+              break;
+            }
+          }
+
+          if(!sp_bit)
+          {
+            /* clean up, we have failed and must now examine the
+             * entry itself
+             * But first lets cache the no result
+             * Creates the type (if necessary).
+            */
+            slapi_entry_vattrcache_merge_sv(e, type, NULL );
+
+          }
+          else
+          {
+            /*
+             * we need to cache the virtual attribute
+             * creates the type (if necessary) and dups
+             * results.
+            */
+            slapi_entry_vattrcache_merge_sv(e, *actual_type_name,
+                            *results );
+          }
+
+          break;
+        }
+      }
+    }
+  }
+  /* If no SP supplied the answer, take it from the entry */
+  if (!sp_bit && !(flags & SLAPI_VIRTUALATTRS_ONLY)) 
+  {
+    rc = 0; /* reset return code (cause an sp must have failed) */
+    *type_name_disposition = my_get.get_name_disposition;
+
+    if (my_get.get_present) {
+      if (flags & SLAPI_VIRTUALATTRS_REQUEST_POINTERS) {
+        *results = my_get.get_present_values;
+        *actual_type_name = my_get.get_type_name;
+      } else {
+        *results = valueset_dup(my_get.get_present_values);
+        if (NULL == *results) {
+          rc = ENOMEM;
+        } else {
+          *actual_type_name = slapi_ch_strdup(my_get.get_type_name);
+          if (NULL == *actual_type_name) {
+            rc = ENOMEM;
+          }
+        }
+      }
+      if (flags & SLAPI_VIRTUALATTRS_REQUEST_POINTERS) {
+          *buffer_flags = SLAPI_VIRTUALATTRS_RETURNED_POINTERS;
+      } else {
+        *buffer_flags = SLAPI_VIRTUALATTRS_RETURNED_COPIES;
+      }
+    } else {
+      rc = SLAPI_VIRTUALATTRS_NOT_FOUND;
+    }
+  }
+  if (use_local_ctx) {
+    /* slapi_pblock_destroy cleans up pb_vattr_context, as well */
+    slapi_pblock_destroy(local_pb);
+  } else {
+    vattr_context_ungrok(&c);
+  }
+  return rc;
 }
 
 /*




More information about the Fedora-directory-commits mailing list