summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2007-11-01 20:24:07 +0000
committerNoriko Hosoi <nhosoi@redhat.com>2007-11-01 20:24:07 +0000
commit91c03a8ad10486ee55ac5830206ce846483a1b69 (patch)
tree88be82c9590cf79d67455f92c74979f3e0cf1645 /ldap/servers/slapd
parent33bdb0dbd7dc03961818e8d58d15908cf6b6c4fc (diff)
downloadds-91c03a8ad10486ee55ac5830206ce846483a1b69.tar.gz
ds-91c03a8ad10486ee55ac5830206ce846483a1b69.tar.xz
ds-91c03a8ad10486ee55ac5830206ce846483a1b69.zip
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.
Diffstat (limited to 'ldap/servers/slapd')
-rw-r--r--ldap/servers/slapd/vattr.c311
1 files changed, 155 insertions, 156 deletions
diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
index 8e34f305..5c22cb05 100644
--- a/ldap/servers/slapd/vattr.c
+++ b/ldap/servers/slapd/vattr.c
@@ -630,163 +630,162 @@ int vattr_test_filter( Slapi_PBlock *pb,
*/
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;
+ /* 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;
+ }
- 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;
+ 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;
}
/*