From f13d630ff98eb5b5505f1db3e7f207175b51b237 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
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