Blame SOURCES/0004-Issue-51076-remove-unnecessary-slapi-entry-dups.patch

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