Author: nkinder
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/memberof In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv4002/ldap/servers/plugins/memberof
Modified Files: memberof.c Log Message: Resolves: 452537 Summary: Fixed infinite recursion issues in memberOf plug-in.
Index: memberof.c =================================================================== RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/memberof/memberof.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- memberof.c 19 Jun 2008 15:18:20 -0000 1.9 +++ memberof.c 25 Jun 2008 18:34:12 -0000 1.10 @@ -901,20 +901,72 @@ op_to_sdn = slapi_sdn_new_dn_byref(op_to); slapi_search_internal_get_entry( op_to_sdn, attrlist, &e, memberof_get_plugin_id()); - slapi_sdn_free(&op_to_sdn); if(!e) { + /* In the case of a delete, we need to worry about the + * missing entry being a nested group. There's a small + * window where another thread may have deleted a nested + * group that our group_dn entry refers to. This has the + * potential of us missing some indirect member entries + * that need to be updated. */ if(LDAP_MOD_DELETE == mod_op) { - /* in the case of delete we must guard against - * having groups in a nested chain having been - * deleted during the window of opportunity - * and we must fall back to testing all members - * of the (potentially deleted group) for valid - * membership given the delete operation that - * triggered this operation - */ - memberof_test_membership(pb, config, group_dn); + Slapi_PBlock *search_pb = slapi_pblock_new(); + Slapi_DN *base_sdn = 0; + Slapi_Backend *be = 0; + char *filter_str = 0; + int n_entries = 0; + + /* We can't tell for sure if the op_to entry is a + * user or a group since the entry doesn't exist + * anymore. We can safely ignore the missing entry + * if no other entries have a memberOf attribute that + * points to the missing entry. */ + be = slapi_be_select(op_to_sdn); + if(be) + { + base_sdn = (Slapi_DN*)slapi_be_getsuffix(be,0); + } + + if(base_sdn) + { + filter_str = slapi_ch_smprintf("(%s=%s)", + config->memberof_attr, op_to); + } + + if(filter_str) + { + slapi_search_internal_set_pb(search_pb, slapi_sdn_get_dn(base_sdn), + LDAP_SCOPE_SUBTREE, filter_str, 0, 0, 0, 0, + memberof_get_plugin_id(), 0); + + if (slapi_search_internal_pb(search_pb)) + { + /* get result and log an error */ + int res = 0; + slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &res); + slapi_log_error( SLAPI_LOG_FATAL, MEMBEROF_PLUGIN_SUBSYSTEM, + "memberof_modop_one_replace_r: error searching for members: " + "%d", res); + } else { + slapi_pblock_get(search_pb, SLAPI_NENTRIES, &n_entries); + + if(n_entries > 0) + { + /* We want to fixup the membership for the + * entries that referred to the missing group + * entry. This will fix the references to + * the missing group as well as the group + * represented by op_this. */ + memberof_test_membership(pb, config, op_to); + } + } + + slapi_free_search_results_internal(search_pb); + slapi_ch_free_string(&filter_str); + } + + slapi_pblock_destroy(search_pb); }
goto bail; @@ -1108,6 +1160,7 @@ }
bail: + slapi_sdn_free(&op_to_sdn); slapi_value_free(&to_dn_val); slapi_value_free(&this_dn_val); slapi_entry_free(e); @@ -1243,51 +1296,62 @@ { int rc = 0; Slapi_Value *val = 0; + Slapi_Value *op_this_val = 0; int last_size = 0; char *last_str = 0; int hint = slapi_attr_first_value(attr, &val);
+ op_this_val = slapi_value_new_string(op_this); + while(val) { char *dn_str = 0; - struct berval *bv = (struct berval *)slapi_value_get_berval(val); + struct berval *bv = 0;
- if(last_size > bv->bv_len) - { - dn_str = last_str; - } - else + /* We don't want to process a memberOf operation on ourselves. */ + if(0 != memberof_compare(config, &val, &op_this_val)) { - int the_size = (bv->bv_len * 2) + 1; + bv = (struct berval *)slapi_value_get_berval(val);
- if(last_str) - slapi_ch_free_string(&last_str); + if(last_size > bv->bv_len) + { + dn_str = last_str; + } + else + { + int the_size = (bv->bv_len * 2) + 1;
- dn_str = (char*)slapi_ch_malloc(the_size); + if(last_str) + slapi_ch_free_string(&last_str);
- last_str = dn_str; - last_size = the_size; - } + dn_str = (char*)slapi_ch_malloc(the_size);
- memset(dn_str, 0, last_size); + last_str = dn_str; + last_size = the_size; + }
- strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len); + memset(dn_str, 0, last_size);
- /* If we're doing a replace (as we would in the MODRDN case), we need - * to specify the new group DN value */ - if(mod == LDAP_MOD_REPLACE) - { - memberof_modop_one_replace_r(pb, config, mod, group_dn, op_this, group_dn, - dn_str, stack); - } - else - { - memberof_modop_one_r(pb, config, mod, group_dn, op_this, dn_str, stack); + strncpy(dn_str, bv->bv_val, (size_t)bv->bv_len); + + /* If we're doing a replace (as we would in the MODRDN case), we need + * to specify the new group DN value */ + if(mod == LDAP_MOD_REPLACE) + { + memberof_modop_one_replace_r(pb, config, mod, group_dn, op_this, + group_dn, dn_str, stack); + } + else + { + memberof_modop_one_r(pb, config, mod, group_dn, op_this, dn_str, stack); + } }
hint = slapi_attr_next_value(attr, hint, &val); }
+ slapi_value_free(&op_this_val); + if(last_str) slapi_ch_free_string(&last_str);