From f13d630ff98eb5b5505f1db3e7f207175b51b237 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Tue, 12 May 2020 13:48:30 -0400 Subject: [PATCH 04/12] Issue 51076 - remove unnecessary slapi entry dups Description: So the problem is that slapi_search_internal_get_entry() duplicates the entry twice. It does that as a convenience where it will allocate a pblock, do the search, copy the entry, free search results from the pblock, and then free the pblock itself. I basically split this function into two functions. One function allocates the pblock, does the search and returns the entry. The other function frees the entries and pblock. 99% of time when we call slapi_search_internal_get_entry() we are just reading it and freeing it. It's not being consumed. In these cases we can use the two function approach eliminates an extra slapi_entry_dup(). Over the time of an operation/connection we can save quite a bit of mallocing/freeing. This could also help with memory fragmentation. ASAN: passed relates: https://pagure.io/389-ds-base/issue/51076 Reviewed by: firstyear & tbordaz(Thanks!) --- ldap/servers/plugins/acctpolicy/acct_config.c | 6 +-- ldap/servers/plugins/acctpolicy/acct_plugin.c | 36 +++++++------- ldap/servers/plugins/acctpolicy/acct_util.c | 6 +-- ldap/servers/plugins/automember/automember.c | 17 +++---- ldap/servers/plugins/dna/dna.c | 23 ++++----- ldap/servers/plugins/memberof/memberof.c | 16 +++---- .../plugins/pam_passthru/pam_ptconfig.c | 10 ++-- .../servers/plugins/pam_passthru/pam_ptimpl.c | 7 +-- .../plugins/pam_passthru/pam_ptpreop.c | 9 ++-- .../plugins/replication/repl5_tot_protocol.c | 5 +- ldap/servers/plugins/uiduniq/uid.c | 23 ++++----- ldap/servers/slapd/daemon.c | 11 ++--- ldap/servers/slapd/modify.c | 12 +++-- ldap/servers/slapd/plugin_internal_op.c | 48 +++++++++++++++++++ ldap/servers/slapd/resourcelimit.c | 13 ++--- ldap/servers/slapd/schema.c | 7 ++- ldap/servers/slapd/slapi-plugin.h | 23 ++++++++- 17 files changed, 161 insertions(+), 111 deletions(-) diff --git a/ldap/servers/plugins/acctpolicy/acct_config.c b/ldap/servers/plugins/acctpolicy/acct_config.c index fe35ba5a0..01e4f319f 100644 --- a/ldap/servers/plugins/acctpolicy/acct_config.c +++ b/ldap/servers/plugins/acctpolicy/acct_config.c @@ -37,6 +37,7 @@ static int acct_policy_entry2config(Slapi_Entry *e, int acct_policy_load_config_startup(Slapi_PBlock *pb __attribute__((unused)), void *plugin_id) { + Slapi_PBlock *entry_pb = NULL; acctPluginCfg *newcfg; Slapi_Entry *config_entry = NULL; Slapi_DN *config_sdn = NULL; @@ -44,8 +45,7 @@ acct_policy_load_config_startup(Slapi_PBlock *pb __attribute__((unused)), void * /* Retrieve the config entry */ config_sdn = slapi_sdn_new_normdn_byref(PLUGIN_CONFIG_DN); - rc = slapi_search_internal_get_entry(config_sdn, NULL, &config_entry, - plugin_id); + rc = slapi_search_get_entry(&entry_pb, config_sdn, NULL, &config_entry, plugin_id); slapi_sdn_free(&config_sdn); if (rc != LDAP_SUCCESS || config_entry == NULL) { @@ -60,7 +60,7 @@ acct_policy_load_config_startup(Slapi_PBlock *pb __attribute__((unused)), void * rc = acct_policy_entry2config(config_entry, newcfg); config_unlock(); - slapi_entry_free(config_entry); + slapi_search_get_entry_done(&entry_pb); return (rc); } diff --git a/ldap/servers/plugins/acctpolicy/acct_plugin.c b/ldap/servers/plugins/acctpolicy/acct_plugin.c index 2a876ad72..c3c32b074 100644 --- a/ldap/servers/plugins/acctpolicy/acct_plugin.c +++ b/ldap/servers/plugins/acctpolicy/acct_plugin.c @@ -209,6 +209,7 @@ done: int acct_bind_preop(Slapi_PBlock *pb) { + Slapi_PBlock *entry_pb = NULL; const char *dn = NULL; Slapi_DN *sdn = NULL; Slapi_Entry *target_entry = NULL; @@ -236,8 +237,7 @@ acct_bind_preop(Slapi_PBlock *pb) goto done; } - ldrc = slapi_search_internal_get_entry(sdn, NULL, &target_entry, - plugin_id); + ldrc = slapi_search_get_entry(&entry_pb, sdn, NULL, &target_entry, plugin_id); /* There was a problem retrieving the entry */ if (ldrc != LDAP_SUCCESS) { @@ -275,7 +275,7 @@ done: slapi_send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, NULL, 0, NULL); } - slapi_entry_free(target_entry); + slapi_search_get_entry_done(&entry_pb); free_acctpolicy(&policy); @@ -293,6 +293,7 @@ done: int acct_bind_postop(Slapi_PBlock *pb) { + Slapi_PBlock *entry_pb = NULL; char *dn = NULL; int ldrc, tracklogin = 0; int rc = 0; /* Optimistic default */ @@ -327,8 +328,7 @@ acct_bind_postop(Slapi_PBlock *pb) covered by an account policy to decide whether we should track */ if (tracklogin == 0) { sdn = slapi_sdn_new_normdn_byref(dn); - ldrc = slapi_search_internal_get_entry(sdn, NULL, &target_entry, - plugin_id); + ldrc = slapi_search_get_entry(&entry_pb, sdn, NULL, &target_entry, plugin_id); if (ldrc != LDAP_SUCCESS) { slapi_log_err(SLAPI_LOG_ERR, POST_PLUGIN_NAME, @@ -355,7 +355,7 @@ done: slapi_send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, NULL, 0, NULL); } - slapi_entry_free(target_entry); + slapi_search_get_entry_done(&entry_pb); slapi_sdn_free(&sdn); @@ -370,11 +370,11 @@ done: static int acct_pre_op(Slapi_PBlock *pb, int modop) { + Slapi_PBlock *entry_pb = NULL; Slapi_DN *sdn = 0; Slapi_Entry *e = 0; Slapi_Mods *smods = 0; LDAPMod **mods; - int free_entry = 0; char *errstr = NULL; int ret = SLAPI_PLUGIN_SUCCESS; @@ -384,28 +384,25 @@ acct_pre_op(Slapi_PBlock *pb, int modop) if (acct_policy_dn_is_config(sdn)) { /* Validate config changes, but don't apply them. - * This allows us to reject invalid config changes - * here at the pre-op stage. Applying the config - * needs to be done at the post-op stage. */ + * This allows us to reject invalid config changes + * here at the pre-op stage. Applying the config + * needs to be done at the post-op stage. */ if (LDAP_CHANGETYPE_ADD == modop) { slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e); - /* If the entry doesn't exist, just bail and - * let the server handle it. */ + /* If the entry doesn't exist, just bail and let the server handle it. */ if (e == NULL) { goto bail; } } else if (LDAP_CHANGETYPE_MODIFY == modop) { /* Fetch the entry being modified so we can - * create the resulting entry for validation. */ + * create the resulting entry for validation. */ if (sdn) { - slapi_search_internal_get_entry(sdn, 0, &e, get_identity()); - free_entry = 1; + slapi_search_get_entry(&entry_pb, sdn, 0, &e, get_identity()); } - /* If the entry doesn't exist, just bail and - * let the server handle it. */ + /* If the entry doesn't exist, just bail and let the server handle it. */ if (e == NULL) { goto bail; } @@ -418,7 +415,7 @@ acct_pre_op(Slapi_PBlock *pb, int modop) /* Apply the mods to create the resulting entry. */ if (mods && (slapi_entry_apply_mods(e, mods) != LDAP_SUCCESS)) { /* The mods don't apply cleanly, so we just let this op go - * to let the main server handle it. */ + * to let the main server handle it. */ goto bailmod; } } else if (modop == LDAP_CHANGETYPE_DELETE) { @@ -439,8 +436,7 @@ bailmod: } bail: - if (free_entry && e) - slapi_entry_free(e); + slapi_search_get_entry_done(&entry_pb); if (ret) { slapi_log_err(SLAPI_LOG_PLUGIN, PRE_PLUGIN_NAME, diff --git a/ldap/servers/plugins/acctpolicy/acct_util.c b/ldap/servers/plugins/acctpolicy/acct_util.c index f25a3202d..f432092fe 100644 --- a/ldap/servers/plugins/acctpolicy/acct_util.c +++ b/ldap/servers/plugins/acctpolicy/acct_util.c @@ -85,6 +85,7 @@ get_attr_string_val(Slapi_Entry *target_entry, char *attr_name) int get_acctpolicy(Slapi_PBlock *pb __attribute__((unused)), Slapi_Entry *target_entry, void *plugin_id, acctPolicy **policy) { + Slapi_PBlock *entry_pb = NULL; Slapi_DN *sdn = NULL; Slapi_Entry *policy_entry = NULL; Slapi_Attr *attr; @@ -123,8 +124,7 @@ get_acctpolicy(Slapi_PBlock *pb __attribute__((unused)), Slapi_Entry *target_ent } sdn = slapi_sdn_new_dn_byref(policy_dn); - ldrc = slapi_search_internal_get_entry(sdn, NULL, &policy_entry, - plugin_id); + ldrc = slapi_search_get_entry(&entry_pb, sdn, NULL, &policy_entry, plugin_id); slapi_sdn_free(&sdn); /* There should be a policy but it can't be retrieved; fatal error */ @@ -160,7 +160,7 @@ dopolicy: done: config_unlock(); slapi_ch_free_string(&policy_dn); - slapi_entry_free(policy_entry); + slapi_search_get_entry_done(&entry_pb); return (rc); } diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c index 7c875c852..39350ad53 100644 --- a/ldap/servers/plugins/automember/automember.c +++ b/ldap/servers/plugins/automember/automember.c @@ -1629,13 +1629,12 @@ automember_update_member_value(Slapi_Entry *member_e, const char *group_dn, char char *member_value = NULL; int rc = 0; Slapi_DN *group_sdn; - Slapi_Entry *group_entry = NULL; /* First thing check that the group still exists */ group_sdn = slapi_sdn_new_dn_byval(group_dn); - rc = slapi_search_internal_get_entry(group_sdn, NULL, &group_entry, automember_get_plugin_id()); + rc = slapi_search_internal_get_entry(group_sdn, NULL, NULL, automember_get_plugin_id()); slapi_sdn_free(&group_sdn); - if (rc != LDAP_SUCCESS || group_entry == NULL) { + if (rc != LDAP_SUCCESS) { if (rc == LDAP_NO_SUCH_OBJECT) { /* the automember group (default or target) does not exist, just skip this definition */ slapi_log_err(SLAPI_LOG_INFO, AUTOMEMBER_PLUGIN_SUBSYSTEM, @@ -1647,10 +1646,8 @@ automember_update_member_value(Slapi_Entry *member_e, const char *group_dn, char "automember_update_member_value - group (default or target) can not be retrieved (%s) err=%d\n", group_dn, rc); } - slapi_entry_free(group_entry); return rc; } - slapi_entry_free(group_entry); /* If grouping_value is dn, we need to fetch the dn instead. */ if (slapi_attr_type_cmp(grouping_value, "dn", SLAPI_TYPE_CMP_EXACT) == 0) { @@ -1752,11 +1749,11 @@ out: static int automember_pre_op(Slapi_PBlock *pb, int modop) { + Slapi_PBlock *entry_pb = NULL; Slapi_DN *sdn = 0; Slapi_Entry *e = 0; Slapi_Mods *smods = 0; LDAPMod **mods; - int free_entry = 0; char *errstr = NULL; int ret = SLAPI_PLUGIN_SUCCESS; @@ -1784,8 +1781,7 @@ automember_pre_op(Slapi_PBlock *pb, int modop) /* Fetch the entry being modified so we can * create the resulting entry for validation. */ if (sdn) { - slapi_search_internal_get_entry(sdn, 0, &e, automember_get_plugin_id()); - free_entry = 1; + slapi_search_get_entry(&entry_pb, sdn, 0, &e, automember_get_plugin_id()); } /* If the entry doesn't exist, just bail and @@ -1799,7 +1795,7 @@ automember_pre_op(Slapi_PBlock *pb, int modop) smods = slapi_mods_new(); slapi_mods_init_byref(smods, mods); - /* Apply the mods to create the resulting entry. */ + /* Apply the mods to create the resulting entry. */ if (mods && (slapi_entry_apply_mods(e, mods) != LDAP_SUCCESS)) { /* The mods don't apply cleanly, so we just let this op go * to let the main server handle it. */ @@ -1831,8 +1827,7 @@ bailmod: } bail: - if (free_entry && e) - slapi_entry_free(e); + slapi_search_get_entry_done(&entry_pb); if (ret) { slapi_log_err(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM, diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c index 1ee271359..16c625bb0 100644 --- a/ldap/servers/plugins/dna/dna.c +++ b/ldap/servers/plugins/dna/dna.c @@ -1178,7 +1178,6 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply) value = slapi_entry_attr_get_charptr(e, DNA_SHARED_CFG_DN); if (value) { - Slapi_Entry *shared_e = NULL; Slapi_DN *sdn = NULL; char *normdn = NULL; char *attrs[2]; @@ -1197,10 +1196,8 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply) /* We don't need attributes */ attrs[0] = "cn"; attrs[1] = NULL; - slapi_search_internal_get_entry(sdn, attrs, &shared_e, getPluginID()); - /* Make sure that the shared config entry exists. */ - if (!shared_e) { + if(slapi_search_internal_get_entry(sdn, attrs, NULL, getPluginID()) != LDAP_SUCCESS) { /* We didn't locate the shared config container entry. Log * a message and skip this config entry. */ slapi_log_err(SLAPI_LOG_ERR, DNA_PLUGIN_SUBSYSTEM, @@ -1210,9 +1207,6 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply) ret = DNA_FAILURE; slapi_sdn_free(&sdn); goto bail; - } else { - slapi_entry_free(shared_e); - shared_e = NULL; } normdn = (char *)slapi_sdn_get_dn(sdn); @@ -1539,6 +1533,7 @@ dna_delete_shared_servers(PRCList **servers) static int dna_load_host_port(void) { + Slapi_PBlock *pb = NULL; int status = DNA_SUCCESS; Slapi_Entry *e = NULL; Slapi_DN *config_dn = NULL; @@ -1554,7 +1549,7 @@ dna_load_host_port(void) config_dn = slapi_sdn_new_ndn_byref("cn=config"); if (config_dn) { - slapi_search_internal_get_entry(config_dn, attrs, &e, getPluginID()); + slapi_search_get_entry(&pb, config_dn, attrs, &e, getPluginID()); slapi_sdn_free(&config_dn); } @@ -1562,8 +1557,8 @@ dna_load_host_port(void) hostname = slapi_entry_attr_get_charptr(e, "nsslapd-localhost"); portnum = slapi_entry_attr_get_charptr(e, "nsslapd-port"); secureportnum = slapi_entry_attr_get_charptr(e, "nsslapd-secureport"); - slapi_entry_free(e); } + slapi_search_get_entry_done(&pb); if (!hostname || !portnum) { status = DNA_FAILURE; @@ -2876,6 +2871,7 @@ bail: static int dna_is_replica_bind_dn(char *range_dn, char *bind_dn) { + Slapi_PBlock *entry_pb = NULL; char *replica_dn = NULL; Slapi_DN *replica_sdn = NULL; Slapi_DN *range_sdn = NULL; @@ -2912,8 +2908,7 @@ dna_is_replica_bind_dn(char *range_dn, char *bind_dn) attrs[2] = 0; /* Find cn=replica entry via search */ - slapi_search_internal_get_entry(replica_sdn, attrs, &e, getPluginID()); - + slapi_search_get_entry(&entry_pb, replica_sdn, attrs, &e, getPluginID()); if (e) { /* Check if the passed in bind dn matches any of the replica bind dns. */ Slapi_Value *bind_dn_sv = slapi_value_new_string(bind_dn); @@ -2927,6 +2922,7 @@ dna_is_replica_bind_dn(char *range_dn, char *bind_dn) attrs[0] = "member"; attrs[1] = "uniquemember"; attrs[2] = 0; + slapi_search_get_entry_done(&entry_pb); for (i = 0; bind_group_dn != NULL && bind_group_dn[i] != NULL; i++) { if (ret) { /* already found a member, just free group */ @@ -2934,14 +2930,14 @@ dna_is_replica_bind_dn(char *range_dn, char *bind_dn) continue; } bind_group_sdn = slapi_sdn_new_normdn_passin(bind_group_dn[i]); - slapi_search_internal_get_entry(bind_group_sdn, attrs, &bind_group_entry, getPluginID()); + slapi_search_get_entry(&entry_pb, bind_group_sdn, attrs, &bind_group_entry, getPluginID()); if (bind_group_entry) { ret = slapi_entry_attr_has_syntax_value(bind_group_entry, "member", bind_dn_sv); if (ret == 0) { ret = slapi_entry_attr_has_syntax_value(bind_group_entry, "uniquemember", bind_dn_sv); } } - slapi_entry_free(bind_group_entry); + slapi_search_get_entry_done(&entry_pb); slapi_sdn_free(&bind_group_sdn); } slapi_ch_free((void **)&bind_group_dn); @@ -2956,7 +2952,6 @@ dna_is_replica_bind_dn(char *range_dn, char *bind_dn) } done: - slapi_entry_free(e); slapi_sdn_free(&range_sdn); slapi_sdn_free(&replica_sdn); diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c index 40bd4b380..e9e1ec4c7 100644 --- a/ldap/servers/plugins/memberof/memberof.c +++ b/ldap/servers/plugins/memberof/memberof.c @@ -884,7 +884,7 @@ memberof_postop_modrdn(Slapi_PBlock *pb) pre_sdn = slapi_entry_get_sdn(pre_e); post_sdn = slapi_entry_get_sdn(post_e); } - + if (pre_sdn && post_sdn && slapi_sdn_compare(pre_sdn, post_sdn) == 0) { /* Regarding memberof plugin, this rename is a no-op * but it can be expensive to process it. So skip it @@ -1466,6 +1466,7 @@ memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op, Slapi int memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op, Slapi_DN *group_sdn, Slapi_DN *op_this_sdn, Slapi_DN *replace_with_sdn, Slapi_DN *op_to_sdn, memberofstringll *stack) { + Slapi_PBlock *entry_pb = NULL; int rc = 0; LDAPMod mod; LDAPMod replace_mod; @@ -1515,8 +1516,7 @@ memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_o } /* determine if this is a group op or single entry */ - slapi_search_internal_get_entry(op_to_sdn, config->groupattrs, - &e, memberof_get_plugin_id()); + slapi_search_get_entry(&entry_pb, op_to_sdn, config->groupattrs, &e, memberof_get_plugin_id()); if (!e) { /* In the case of a delete, we need to worry about the * missing entry being a nested group. There's a small @@ -1751,7 +1751,7 @@ memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_o bail: slapi_value_free(&to_dn_val); slapi_value_free(&this_dn_val); - slapi_entry_free(e); + slapi_search_get_entry_done(&entry_pb); return rc; } @@ -2368,6 +2368,7 @@ bail: int memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, Slapi_Value *memberdn) { + Slapi_PBlock *pb = NULL; int rc = 0; Slapi_DN *sdn = 0; Slapi_Entry *group_e = 0; @@ -2376,8 +2377,8 @@ memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, Slapi_Va sdn = slapi_sdn_new_normdn_byref(slapi_value_get_string(groupdn)); - slapi_search_internal_get_entry(sdn, config->groupattrs, - &group_e, memberof_get_plugin_id()); + slapi_search_get_entry(&pb, sdn, config->groupattrs, + &group_e, memberof_get_plugin_id()); if (group_e) { /* See if memberdn is referred to by any of the group attributes. */ @@ -2388,9 +2389,8 @@ memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, Slapi_Va break; } } - - slapi_entry_free(group_e); } + slapi_search_get_entry_done(&pb); slapi_sdn_free(&sdn); return rc; diff --git a/ldap/servers/plugins/pam_passthru/pam_ptconfig.c b/ldap/servers/plugins/pam_passthru/pam_ptconfig.c index 46a76d884..cbec2ec40 100644 --- a/ldap/servers/plugins/pam_passthru/pam_ptconfig.c +++ b/ldap/servers/plugins/pam_passthru/pam_ptconfig.c @@ -749,22 +749,22 @@ pam_passthru_get_config(Slapi_DN *bind_sdn) if (pam_passthru_check_suffix(cfg, bind_sdn) == LDAP_SUCCESS) { if (cfg->slapi_filter) { /* A filter is configured, so see if the bind entry is a match. */ + Slapi_PBlock *entry_pb = NULL; Slapi_Entry *test_e = NULL; /* Fetch the bind entry */ - slapi_search_internal_get_entry(bind_sdn, NULL, &test_e, - pam_passthruauth_get_plugin_identity()); + slapi_search_get_entry(&entry_pb, bind_sdn, NULL, &test_e, + pam_passthruauth_get_plugin_identity()); /* If the entry doesn't exist, just fall through to the main server code */ if (test_e) { /* Evaluate the filter. */ if (LDAP_SUCCESS == slapi_filter_test_simple(test_e, cfg->slapi_filter)) { /* This is a match. */ - slapi_entry_free(test_e); + slapi_search_get_entry_done(&entry_pb); goto done; } - - slapi_entry_free(test_e); + slapi_search_get_entry_done(&entry_pb); } } else { /* There is no filter to check, so this is a match. */ diff --git a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c index 7f5fb02c4..5b43f8d1f 100644 --- a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c +++ b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c @@ -81,11 +81,12 @@ derive_from_bind_dn(Slapi_PBlock *pb __attribute__((unused)), const Slapi_DN *bi static char * derive_from_bind_entry(Slapi_PBlock *pb, const Slapi_DN *bindsdn, MyStrBuf *pam_id, char *map_ident_attr, int *locked) { + Slapi_PBlock *entry_pb = NULL; Slapi_Entry *entry = NULL; char *attrs[] = {NULL, NULL}; attrs[0] = map_ident_attr; - int rc = slapi_search_internal_get_entry((Slapi_DN *)bindsdn, attrs, &entry, - pam_passthruauth_get_plugin_identity()); + int32_t rc = slapi_search_get_entry(&entry_pb, (Slapi_DN *)bindsdn, attrs, &entry, + pam_passthruauth_get_plugin_identity()); if (rc != LDAP_SUCCESS) { slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM, @@ -108,7 +109,7 @@ derive_from_bind_entry(Slapi_PBlock *pb, const Slapi_DN *bindsdn, MyStrBuf *pam_ init_my_str_buf(pam_id, val); } - slapi_entry_free(entry); + slapi_search_get_entry_done(&entry_pb); return pam_id->str; } diff --git a/ldap/servers/plugins/pam_passthru/pam_ptpreop.c b/ldap/servers/plugins/pam_passthru/pam_ptpreop.c index 3d0067531..5bca823ff 100644 --- a/ldap/servers/plugins/pam_passthru/pam_ptpreop.c +++ b/ldap/servers/plugins/pam_passthru/pam_ptpreop.c @@ -526,6 +526,7 @@ done: static int pam_passthru_preop(Slapi_PBlock *pb, int modtype) { + Slapi_PBlock *entry_pb = NULL; Slapi_DN *sdn = NULL; Slapi_Entry *e = NULL; LDAPMod **mods; @@ -555,8 +556,8 @@ pam_passthru_preop(Slapi_PBlock *pb, int modtype) case LDAP_CHANGETYPE_MODIFY: /* Fetch the entry being modified so we can * create the resulting entry for validation. */ - slapi_search_internal_get_entry(sdn, 0, &e, - pam_passthruauth_get_plugin_identity()); + slapi_search_get_entry(&entry_pb, sdn, 0, &e, + pam_passthruauth_get_plugin_identity()); /* If the entry doesn't exist, just bail and * let the server handle it. */ @@ -576,9 +577,6 @@ pam_passthru_preop(Slapi_PBlock *pb, int modtype) /* Don't bail here, as we need to free the entry. */ } } - - /* Free the entry. */ - slapi_entry_free(e); break; case LDAP_CHANGETYPE_DELETE: case LDAP_CHANGETYPE_MODDN: @@ -591,6 +589,7 @@ pam_passthru_preop(Slapi_PBlock *pb, int modtype) } bail: + slapi_search_get_entry_done(&entry_pb); /* If we are refusing the operation, return the result to the client. */ if (ret) { slapi_send_ldap_result(pb, ret, NULL, returntext, 0, NULL); diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c index 3b65d6b20..a25839f21 100644 --- a/ldap/servers/plugins/replication/repl5_tot_protocol.c +++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c @@ -469,7 +469,8 @@ retry: */ /* Get suffix */ Slapi_Entry *suffix = NULL; - rc = slapi_search_internal_get_entry(area_sdn, NULL, &suffix, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION)); + Slapi_PBlock *suffix_pb = NULL; + rc = slapi_search_get_entry(&suffix_pb, area_sdn, NULL, &suffix, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION)); if (rc) { slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "repl5_tot_run - Unable to " "get the suffix entry \"%s\".\n", @@ -517,7 +518,7 @@ retry: LDAP_SCOPE_SUBTREE, "(parentid>=1)", NULL, 0, ctrls, NULL, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), OP_FLAG_BULK_IMPORT); cb_data.num_entries = 0UL; - slapi_entry_free(suffix); + slapi_search_get_entry_done(&suffix_pb); } else { /* Original total update */ /* we need to provide managedsait control so that referral entries can diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c index d7ccf0e07..e69012204 100644 --- a/ldap/servers/plugins/uiduniq/uid.c +++ b/ldap/servers/plugins/uiduniq/uid.c @@ -1254,6 +1254,7 @@ preop_modify(Slapi_PBlock *pb) static int preop_modrdn(Slapi_PBlock *pb) { + Slapi_PBlock *entry_pb = NULL; int result = LDAP_SUCCESS; Slapi_Entry *e = NULL; Slapi_Value *sv_requiredObjectClass = NULL; @@ -1351,7 +1352,7 @@ preop_modrdn(Slapi_PBlock *pb) /* Get the entry that is being renamed so we can make a dummy copy * of what it will look like after the rename. */ - err = slapi_search_internal_get_entry(sdn, NULL, &e, plugin_identity); + err = slapi_search_get_entry(&entry_pb, sdn, NULL, &e, plugin_identity); if (err != LDAP_SUCCESS) { result = uid_op_error(35); /* We want to return a no such object error if the target doesn't exist. */ @@ -1371,24 +1372,24 @@ preop_modrdn(Slapi_PBlock *pb) /* - * Check if it has the required object class - */ + * Check if it has the required object class + */ if (requiredObjectClass && !slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS, sv_requiredObjectClass)) { break; } /* - * Find any unique attribute data in the new RDN - */ + * Find any unique attribute data in the new RDN + */ for (i = 0; attrNames && attrNames[i]; i++) { err = slapi_entry_attr_find(e, attrNames[i], &attr); if (!err) { /* - * Passed all the requirements - this is an operation we - * need to enforce uniqueness on. Now find all parent entries - * with the marker object class, and do a search for each one. - */ + * Passed all the requirements - this is an operation we + * need to enforce uniqueness on. Now find all parent entries + * with the marker object class, and do a search for each one. + */ if (NULL != markerObjectClass) { /* Subtree defined by location of marker object class */ result = findSubtreeAndSearch(slapi_entry_get_sdn(e), attrNames, attr, NULL, @@ -1407,8 +1408,8 @@ preop_modrdn(Slapi_PBlock *pb) END /* Clean-up */ slapi_value_free(&sv_requiredObjectClass); - if (e) - slapi_entry_free(e); + + slapi_search_get_entry_done(&entry_pb); if (result) { slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name, diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c index 65f23363a..a70f40316 100644 --- a/ldap/servers/slapd/daemon.c +++ b/ldap/servers/slapd/daemon.c @@ -1916,18 +1916,13 @@ slapd_bind_local_user(Connection *conn) char *root_dn = config_get_ldapi_root_dn(); if (root_dn) { + Slapi_PBlock *entry_pb = NULL; Slapi_DN *edn = slapi_sdn_new_dn_byref( slapi_dn_normalize(root_dn)); Slapi_Entry *e = 0; /* root might be locked too! :) */ - ret = slapi_search_internal_get_entry( - edn, 0, - &e, - (void *)plugin_get_default_component_id() - - ); - + ret = slapi_search_get_entry(&entry_pb, edn, 0, &e, (void *)plugin_get_default_component_id()); if (0 == ret && e) { ret = slapi_check_account_lock( 0, /* pb not req */ @@ -1955,7 +1950,7 @@ slapd_bind_local_user(Connection *conn) root_map_free: /* root_dn consumed by bind creds set */ slapi_sdn_free(&edn); - slapi_entry_free(e); + slapi_search_get_entry_done(&entry_pb); ret = 0; } } diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c index bbc0ab71a..259bedfff 100644 --- a/ldap/servers/slapd/modify.c +++ b/ldap/servers/slapd/modify.c @@ -592,6 +592,7 @@ modify_internal_pb(Slapi_PBlock *pb) static void op_shared_modify(Slapi_PBlock *pb, int pw_change, char *old_pw) { + Slapi_PBlock *entry_pb = NULL; Slapi_Backend *be = NULL; Slapi_Entry *pse; Slapi_Entry *referral; @@ -723,7 +724,7 @@ op_shared_modify(Slapi_PBlock *pb, int pw_change, char *old_pw) * 2. If yes, then if the mods contain any passwdpolicy specific attributes. * 3. If yes, then it invokes corrosponding checking function. */ - if (!repl_op && !internal_op && normdn && (e = get_entry(pb, normdn))) { + if (!repl_op && !internal_op && normdn && slapi_search_get_entry(&entry_pb, sdn, NULL, &e, NULL) == LDAP_SUCCESS) { Slapi_Value target; slapi_value_init(&target); slapi_value_set_string(&target, "passwordpolicy"); @@ -1072,7 +1073,7 @@ free_and_return : { slapi_entry_free(epre); slapi_entry_free(epost); } - slapi_entry_free(e); + slapi_search_get_entry_done(&entry_pb); if (be) slapi_be_Unlock(be); @@ -1202,12 +1203,13 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M if (!internal_op) { /* slapi_acl_check_mods needs an array of LDAPMods, but * we're really only interested in the one password mod. */ + Slapi_PBlock *entry_pb = NULL; LDAPMod *mods[2]; mods[0] = mod; mods[1] = NULL; /* We need to actually fetch the target here to use for ACI checking. */ - slapi_search_internal_get_entry(&sdn, NULL, &e, (void *)plugin_get_default_component_id()); + slapi_search_get_entry(&entry_pb, &sdn, NULL, &e, NULL); /* Create a bogus entry with just the target dn if we were unable to * find the actual entry. This will only be used for checking the ACIs. */ @@ -1238,9 +1240,12 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M } send_ldap_result(pb, res, NULL, errtxt, 0, NULL); slapi_ch_free_string(&errtxt); + slapi_search_get_entry_done(&entry_pb); rc = -1; goto done; } + /* done with slapi entry e */ + slapi_search_get_entry_done(&entry_pb); /* * If this mod is being performed by a password administrator/rootDN, @@ -1353,7 +1358,6 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M valuearray_free(&values); done: - slapi_entry_free(e); slapi_sdn_done(&sdn); slapi_ch_free_string(&proxydn); slapi_ch_free_string(&proxystr); diff --git a/ldap/servers/slapd/plugin_internal_op.c b/ldap/servers/slapd/plugin_internal_op.c index 9da266b61..a140e7988 100644 --- a/ldap/servers/slapd/plugin_internal_op.c +++ b/ldap/servers/slapd/plugin_internal_op.c @@ -882,3 +882,51 @@ slapi_search_internal_get_entry(Slapi_DN *dn, char **attrs, Slapi_Entry **ret_en int_search_pb = NULL; return rc; } + +int32_t +slapi_search_get_entry(Slapi_PBlock **pb, Slapi_DN *dn, char **attrs, Slapi_Entry **ret_entry, void *component_identity) +{ + Slapi_Entry **entries = NULL; + int32_t rc = 0; + void *component = component_identity; + + if (ret_entry) { + *ret_entry = NULL; + } + + if (component == NULL) { + component = (void *)plugin_get_default_component_id(); + } + + if (*pb == NULL) { + *pb = slapi_pblock_new(); + } + slapi_search_internal_set_pb(*pb, slapi_sdn_get_dn(dn), LDAP_SCOPE_BASE, + "(|(objectclass=*)(objectclass=ldapsubentry))", + attrs, 0, NULL, NULL, component, 0 ); + slapi_search_internal_pb(*pb); + slapi_pblock_get(*pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); + if (LDAP_SUCCESS == rc) { + slapi_pblock_get(*pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); + if (NULL != entries && NULL != entries[0]) { + /* Only need to dup the entry if the caller passed ret_entry in. */ + if (ret_entry) { + *ret_entry = entries[0]; + } + } else { + rc = LDAP_NO_SUCH_OBJECT; + } + } + + return rc; +} + +void +slapi_search_get_entry_done(Slapi_PBlock **pb) +{ + if (pb && *pb) { + slapi_free_search_results_internal(*pb); + slapi_pblock_destroy(*pb); + *pb = NULL; + } +} diff --git a/ldap/servers/slapd/resourcelimit.c b/ldap/servers/slapd/resourcelimit.c index 705344c84..9c2619716 100644 --- a/ldap/servers/slapd/resourcelimit.c +++ b/ldap/servers/slapd/resourcelimit.c @@ -305,22 +305,17 @@ reslimit_get_ext(Slapi_Connection *conn, const char *logname, SLAPIResLimitConnD int reslimit_update_from_dn(Slapi_Connection *conn, Slapi_DN *dn) { - Slapi_Entry *e; + Slapi_PBlock *pb = NULL; + Slapi_Entry *e = NULL; int rc; - e = NULL; if (dn != NULL) { - char **attrs = reslimit_get_registered_attributes(); - (void)slapi_search_internal_get_entry(dn, attrs, &e, reslimit_componentid); + slapi_search_get_entry(&pb, dn, attrs, &e, reslimit_componentid); charray_free(attrs); } - rc = reslimit_update_from_entry(conn, e); - - if (NULL != e) { - slapi_entry_free(e); - } + slapi_search_get_entry_done(&pb); return (rc); } diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c index d44b03b0e..bf7e59f75 100644 --- a/ldap/servers/slapd/schema.c +++ b/ldap/servers/slapd/schema.c @@ -341,6 +341,7 @@ schema_policy_add_action(Slapi_Entry *entry, char *attrName, schema_item_t **lis static void schema_load_repl_policy(const char *dn, repl_schema_policy_t *replica) { + Slapi_PBlock *pb = NULL; Slapi_DN sdn; Slapi_Entry *entry = NULL; schema_item_t *schema_item, *next; @@ -369,8 +370,7 @@ schema_load_repl_policy(const char *dn, repl_schema_policy_t *replica) /* Load the replication policy of the schema */ slapi_sdn_init_dn_byref(&sdn, dn); - if (slapi_search_internal_get_entry(&sdn, NULL, &entry, plugin_get_default_component_id()) == LDAP_SUCCESS) { - + if (slapi_search_get_entry(&pb, &sdn, NULL, &entry, plugin_get_default_component_id()) == LDAP_SUCCESS) { /* fill the policies (accept/reject) regarding objectclass */ schema_policy_add_action(entry, ATTR_SCHEMA_UPDATE_OBJECTCLASS_ACCEPT, &replica->objectclasses); schema_policy_add_action(entry, ATTR_SCHEMA_UPDATE_OBJECTCLASS_REJECT, &replica->objectclasses); @@ -378,9 +378,8 @@ schema_load_repl_policy(const char *dn, repl_schema_policy_t *replica) /* fill the policies (accept/reject) regarding attribute */ schema_policy_add_action(entry, ATTR_SCHEMA_UPDATE_ATTRIBUTE_ACCEPT, &replica->attributes); schema_policy_add_action(entry, ATTR_SCHEMA_UPDATE_ATTRIBUTE_REJECT, &replica->attributes); - - slapi_entry_free(entry); } + slapi_search_get_entry_done(&pb); slapi_sdn_done(&sdn); } diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index 0e3857068..be1e52e4d 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -5972,7 +5972,7 @@ void slapi_seq_internal_set_pb(Slapi_PBlock *pb, char *ibase, int type, char *at /* * slapi_search_internal_get_entry() finds an entry given a dn. It returns - * an LDAP error code (LDAP_SUCCESS if all goes well). + * an LDAP error code (LDAP_SUCCESS if all goes well). Caller must free ret_entry */ int slapi_search_internal_get_entry(Slapi_DN *dn, char **attrlist, Slapi_Entry **ret_entry, void *caller_identity); @@ -8296,6 +8296,27 @@ uint64_t slapi_atomic_decr_64(uint64_t *ptr, int memorder); /* helper function */ const char * slapi_fetch_attr(Slapi_Entry *e, const char *attrname, char *default_val); +/** + * Get a Slapi_Entry via an internal search. The caller then needs to call + * slapi_get_entry_done() to free any resources allocated to get the entry + * + * \param pb - slapi_pblock pointer (the function will allocate if necessary) + * \param dn - Slapi_DN of the entry to retrieve + * \param attrs - char list of attributes to get + * \param ret_entry - pointer to a Slapi_entry wer the returned entry is stored + * \param component_identity - plugin component + * + * \return - ldap result code + */ +int32_t slapi_search_get_entry(Slapi_PBlock **pb, Slapi_DN *dn, char **attrs, Slapi_Entry **ret_entry, void *component_identity); + +/** + * Free the resources allocated by slapi_search_get_entry() + * + * \param pb - slapi_pblock pointer + */ +void slapi_search_get_entry_done(Slapi_PBlock **pb); + #ifdef __cplusplus } #endif -- 2.26.2