s4-dsdb: Add mem_ctx argument to samdb_ntds_settings_dn
authorAndrew Bartlett <abartlet@samba.org>
Tue, 14 Aug 2012 06:08:47 +0000 (16:08 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 14 Aug 2012 08:05:14 +0000 (10:05 +0200)
As this value is calculated new each time, we need to give it a context to live on.

If the value is the forced value during provision, a reference is taken.

This was responsible for the memory leak in the replication process.  In the
example I was given, this DN appeared in memory 13596 times!

Andrew Bartlett

Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Tue Aug 14 10:05:14 CEST 2012 on sn-devel-104

14 files changed:
source4/dsdb/common/util.c
source4/dsdb/kcc/kcc_connection.c
source4/dsdb/kcc/kcc_periodic.c
source4/dsdb/kcc/kcc_topology.c
source4/dsdb/repl/drepl_fsmo.c
source4/dsdb/repl/drepl_partitions.c
source4/dsdb/repl/drepl_ridalloc.c
source4/dsdb/samdb/ldb_modules/objectclass.c
source4/dsdb/samdb/ldb_modules/ridalloc.c
source4/dsdb/samdb/ldb_modules/rootdse.c
source4/dsdb/samdb/ldb_modules/util.c
source4/dsdb/schema/schema_init.c
source4/rpc_server/drsuapi/dcesrv_drsuapi.c
source4/rpc_server/drsuapi/getncchanges.c

index dca7a4409ed761fdaf15d22a12216fd71c37323e..251e17759b4f27a9add07c0a4da53ec40b4322e0 100644 (file)
@@ -1241,7 +1241,7 @@ failed:
 /*
   work out the ntds settings dn for the current open ldb
 */
-struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
+struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
 {
        TALLOC_CTX *tmp_ctx;
        const char *root_attrs[] = { "dsServiceName", NULL };
@@ -1252,10 +1252,10 @@ struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
        /* see if we have a cached copy */
        settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "forced.ntds_settings_dn");
        if (settings_dn) {
-               return settings_dn;
+               return talloc_reference(mem_ctx, settings_dn);
        }
 
-       tmp_ctx = talloc_new(ldb);
+       tmp_ctx = talloc_new(mem_ctx);
        if (tmp_ctx == NULL) {
                goto failed;
        }
@@ -1277,7 +1277,7 @@ struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
         * we could not handle server renames at runtime. Only
         * provision sets up forced.ntds_settings_dn */
 
-       talloc_steal(ldb, settings_dn);
+       talloc_steal(mem_ctx, settings_dn);
        talloc_free(tmp_ctx);
 
        return settings_dn;
@@ -1310,7 +1310,7 @@ const struct GUID *samdb_ntds_invocation_id(struct ldb_context *ldb)
                goto failed;
        }
 
-       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
+       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
        if (ret) {
                goto failed;
        }
@@ -1403,7 +1403,7 @@ const struct GUID *samdb_ntds_objectGUID(struct ldb_context *ldb)
                goto failed;
        }
 
-       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
+       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
        if (ret) {
                goto failed;
        }
@@ -1478,7 +1478,15 @@ failed:
 */
 struct ldb_dn *samdb_server_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
 {
-       return ldb_dn_get_parent(mem_ctx, samdb_ntds_settings_dn(ldb));
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       struct ldb_dn *dn;
+       if (!tmp_ctx) {
+               return NULL;
+       }
+       dn = ldb_dn_get_parent(mem_ctx, samdb_ntds_settings_dn(ldb, tmp_ctx));
+       talloc_free(tmp_ctx);
+       return dn;
+       
 }
 
 /*
@@ -1798,7 +1806,7 @@ bool samdb_is_pdc(struct ldb_context *ldb)
                goto failed;
        }
 
-       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), pdc) == 0) {
+       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb, tmp_ctx), pdc) == 0) {
                is_pdc = true;
        } else {
                is_pdc = false;
@@ -2981,7 +2989,7 @@ int samdb_ntds_options(struct ldb_context *ldb, uint32_t *options)
                goto failed;
        }
 
-       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
+       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
        if (ret != LDB_SUCCESS) {
                goto failed;
        }
@@ -3008,7 +3016,7 @@ const char* samdb_ntds_object_category(TALLOC_CTX *tmp_ctx, struct ldb_context *
        int ret;
        struct ldb_result *res;
 
-       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb), LDB_SCOPE_BASE, attrs, NULL);
+       ret = ldb_search(ldb, tmp_ctx, &res, samdb_ntds_settings_dn(ldb, tmp_ctx), LDB_SCOPE_BASE, attrs, NULL);
        if (ret != LDB_SUCCESS) {
                goto failed;
        }
index 266f753c37dce9f3f281dba917c830ffd0232111..ea6383342c46651dc26cb282a20437a5e8d4553c 100644 (file)
@@ -51,7 +51,7 @@ static int kccsrv_add_connection(struct kccsrv_service *s,
                ret = LDB_ERR_OPERATIONS_ERROR;
                goto done;
        }
-       new_dn = samdb_ntds_settings_dn(s->samdb);
+       new_dn = samdb_ntds_settings_dn(s->samdb, tmp_ctx);
        if (!new_dn) {
                DEBUG(0, ("failed to find NTDS settings\n"));
                ret = LDB_ERR_OPERATIONS_ERROR;
@@ -198,7 +198,7 @@ struct kcc_connection_list *kccsrv_find_connections(struct kccsrv_service *s,
                return NULL;
        }
 
-       base_dn = samdb_ntds_settings_dn(s->samdb);
+       base_dn = samdb_ntds_settings_dn(s->samdb, tmp_ctx);
        if (!base_dn) {
                DEBUG(0, ("failed to find our own NTDS settings DN\n"));
                talloc_free(tmp_ctx);
index e3792300de0c00636f55aa128b30e32c23413ce5..f96347f423ec49ab5969878a8938321770b2338b 100644 (file)
@@ -392,7 +392,7 @@ static int kccsrv_gc_update(struct kccsrv_service *s, struct ldb_result *res)
        }
 
        /* get a list of what NCs we are already replicating */
-       ret = dsdb_search_dn(s->samdb, tmp_ctx, &res2, samdb_ntds_settings_dn(s->samdb), attrs2, 0);
+       ret = dsdb_search_dn(s->samdb, tmp_ctx, &res2, samdb_ntds_settings_dn(s->samdb, tmp_ctx), attrs2, 0);
        if (ret != LDB_SUCCESS) {
                DEBUG(1,("Failed to get our NC list attributes for GC update - %s\n", ldb_errstring(s->samdb)));
                talloc_free(tmp_ctx);
index 9697ec12f70d3222f6bd4dd89de36b259cb1df78..2a9f2dd15c6a80152bfd47058aae38be923ff009 100644 (file)
@@ -1007,7 +1007,7 @@ static NTSTATUS kcctpl_bridgehead_dc_failed(struct ldb_context *ldb,
        tmp_ctx = talloc_new(ldb);
        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
 
-       settings_dn = samdb_ntds_settings_dn(ldb);
+       settings_dn = samdb_ntds_settings_dn(ldb, tmp_ctx);
        if (!settings_dn) {
                DEBUG(1, (__location__ ": failed to find our own NTDS Settings "
                          "DN\n"));
index db6385315b4e41716df6e7e9907e3631431a4701..4a1d08ac1b034432ac9e7340317faa67414593b0 100644 (file)
@@ -77,8 +77,9 @@ NTSTATUS drepl_take_FSMO_role(struct irpc_message *msg,
        enum drepl_role_master role = r->in.role;
        struct fsmo_role_state *fsmo;
 
-       ntds_dn = samdb_ntds_settings_dn(service->samdb);
+       ntds_dn = samdb_ntds_settings_dn(service->samdb, tmp_ctx);
        if (!ntds_dn) {
+               talloc_free(tmp_ctx);
                r->out.result = WERR_DS_DRA_INTERNAL_ERROR;
                return NT_STATUS_OK;
        }
@@ -86,6 +87,7 @@ NTSTATUS drepl_take_FSMO_role(struct irpc_message *msg,
        werr = dsdb_get_fsmo_role_info(tmp_ctx, service->samdb, role,
                                       &fsmo_role_dn, &role_owner_dn);
        if (!W_ERROR_IS_OK(werr)) {
+               talloc_free(tmp_ctx);
                r->out.result = werr;
                return NT_STATUS_OK;
        }
@@ -106,6 +108,7 @@ NTSTATUS drepl_take_FSMO_role(struct irpc_message *msg,
                DEBUG(2,("Unknown role %u in role transfer\n",
                         (unsigned)role));
                r->out.result = WERR_DS_DRA_INTERNAL_ERROR;
+               talloc_free(tmp_ctx);
                return NT_STATUS_OK;
        }
 
@@ -115,6 +118,7 @@ NTSTATUS drepl_take_FSMO_role(struct irpc_message *msg,
                         ldb_dn_get_linearized(fsmo_role_dn),
                         ldb_dn_get_linearized(role_owner_dn)));
                r->out.result = WERR_OK;
+               talloc_free(tmp_ctx);
                return NT_STATUS_OK;
        }
 
@@ -134,11 +138,13 @@ NTSTATUS drepl_take_FSMO_role(struct irpc_message *msg,
                                         fsmo);
        if (!W_ERROR_IS_OK(werr)) {
                r->out.result = werr;
+               talloc_free(tmp_ctx);
                return NT_STATUS_OK;
        }
 
        /* mark this message to be answered later */
        msg->defer_reply = true;
        dreplsrv_run_pending_ops(service);
+       talloc_free(tmp_ctx);
        return NT_STATUS_OK;
 }
index 3aa715a92d20bd59ed30ac53248199064f53fc85..7464dc15546508b790470781b0e70a68b9ad4bae 100644 (file)
@@ -52,7 +52,7 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
        tmp_ctx = talloc_new(s);
        W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
 
-       ntds_dn = samdb_ntds_settings_dn(s->samdb);
+       ntds_dn = samdb_ntds_settings_dn(s->samdb, tmp_ctx);
        if (!ntds_dn) {
                DEBUG(1,(__location__ ": Unable to find ntds_dn: %s\n", ldb_errstring(s->samdb)));
                talloc_free(tmp_ctx);
index 6dcd9efd8a1c296eea7dcdd0ebbfef75b93f2822..c817c319f2cf38c481d8d93a9af7861016cfe5bf 100644 (file)
@@ -95,7 +95,7 @@ static int drepl_ridalloc_pool_exhausted(struct ldb_context *ldb,
        *exhausted = false;
        *_alloc_pool = UINT64_MAX;
 
-       server_dn = ldb_dn_get_parent(tmp_ctx, samdb_ntds_settings_dn(ldb));
+       server_dn = ldb_dn_get_parent(tmp_ctx, samdb_ntds_settings_dn(ldb, tmp_ctx));
        if (!server_dn) {
                talloc_free(tmp_ctx);
                return ldb_operr(ldb);
@@ -208,7 +208,7 @@ WERROR dreplsrv_ridalloc_check_rid_pool(struct dreplsrv_service *service)
                return WERR_DS_DRA_INTERNAL_ERROR;
        }
 
-       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) == 0) {
+       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb, tmp_ctx), fsmo_role_dn) == 0) {
                /* we are the RID Manager - no need to do a
                   DRSUAPI_EXOP_FSMO_RID_ALLOC */
                talloc_free(tmp_ctx);
index d431367b5a0aafc81556b1e4c14debbabeff6313..7d34b4e8c3b5df12111fa44f4a0e50f850eb2f75 100644 (file)
@@ -1298,7 +1298,7 @@ static int objectclass_do_delete(struct oc_context *ac)
        }
 
        /* DC's ntDSDSA object */
-       if (ldb_dn_compare(ac->req->op.del.dn, samdb_ntds_settings_dn(ldb)) == 0) {
+       if (ldb_dn_compare(ac->req->op.del.dn, samdb_ntds_settings_dn(ldb, ac)) == 0) {
                ldb_asprintf_errstring(ldb, "objectclass: Cannot delete %s, it's the DC's ntDSDSA object!",
                                       ldb_dn_get_linearized(ac->req->op.del.dn));
                return LDB_ERR_UNWILLING_TO_PERFORM;
index 2cef1c445f6224e6e8895a53886aaca1611971ad..915248c440fb90c8c2c019c7255a1c4c36333402 100644 (file)
@@ -407,7 +407,7 @@ static int ridalloc_create_own_rid_set(struct ldb_module *module, TALLOC_CTX *me
                return ret;
        }
 
-       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {
+       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb, tmp_ctx), fsmo_role_dn) != 0) {
                ridalloc_poke_rid_manager(module);
                ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh");
                talloc_free(tmp_ctx);
@@ -448,7 +448,7 @@ static int ridalloc_new_own_pool(struct ldb_module *module, uint64_t *new_pool,
                return ret;
        }
 
-       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {
+       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb, tmp_ctx), fsmo_role_dn) != 0) {
                ridalloc_poke_rid_manager(module);
                ldb_asprintf_errstring(ldb, "Remote RID Set allocation needs refresh");
                talloc_free(tmp_ctx);
index 6859d04e59fd3a036c6c15d1f5b1e26df8d65d11..9ae5b20eb1fe8018fb987248471968a68710a017 100644 (file)
@@ -197,7 +197,7 @@ static int dsdb_module_we_are_master(struct ldb_module *module, struct ldb_dn *d
                return LDB_SUCCESS;
        }
 
-       *master = (ldb_dn_compare(owner_dn, samdb_ntds_settings_dn(ldb_module_get_ctx(module))) == 0);
+       *master = (ldb_dn_compare(owner_dn, samdb_ntds_settings_dn(ldb_module_get_ctx(module), tmp_ctx)) == 0);
        talloc_free(tmp_ctx);
        return LDB_SUCCESS;
 }
@@ -1073,7 +1073,7 @@ static int rootdse_enable_recycle_bin(struct ldb_module *module,struct ldb_conte
        }
 
        tmp_ctx = talloc_new(mem_ctx);
-       ntds_settings_dn = samdb_ntds_settings_dn(ldb);
+       ntds_settings_dn = samdb_ntds_settings_dn(ldb, tmp_ctx);
        if (!ntds_settings_dn) {
                talloc_free(tmp_ctx);
                return ldb_error(ldb, LDB_ERR_OPERATIONS_ERROR, "Failed to find NTDS settings DN");
index 0f1a61236f114fb118f11046834485b2dfc6dcef..253d5c1d2ccbac123e71ebc55e38dc53c02af3ce 100644 (file)
@@ -691,15 +691,16 @@ int dsdb_check_optional_feature(struct ldb_module *module, struct GUID op_featur
        struct ldb_message_element *el;
        struct ldb_dn *feature_dn;
 
-       feature_dn = samdb_ntds_settings_dn(ldb_module_get_ctx(module));
+       tmp_ctx = talloc_new(ldb);
+
+       feature_dn = samdb_ntds_settings_dn(ldb_module_get_ctx(module), tmp_ctx);
        if (feature_dn == NULL) {
+               talloc_free(tmp_ctx);
                return ldb_operr(ldb_module_get_ctx(module));
        }
 
        *feature_enabled = false;
 
-       tmp_ctx = talloc_new(ldb);
-
        ret = dsdb_module_search_dn(module, tmp_ctx, &res, feature_dn, attrs, DSDB_FLAG_NEXT_MODULE, NULL);
        if (ret != LDB_SUCCESS) {
                ldb_asprintf_errstring(ldb,
index 1771b267cd098014de8b1f75dffc7c46108bb7de..8385ac2def921b3806f703e9d2f59d7d89ce2c3d 100644 (file)
@@ -897,7 +897,7 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
        }
 
        schema->fsmo.master_dn = ldb_msg_find_attr_as_dn(ldb, schema, schema_res->msgs[0], "fSMORoleOwner");
-       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), schema->fsmo.master_dn) == 0) {
+       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb, tmp_ctx), schema->fsmo.master_dn) == 0) {
                schema->fsmo.we_are_master = true;
        } else {
                schema->fsmo.we_are_master = false;
index b170ec3e239027b32eec3d223cbeefa286686022..1d51ce879a1e298cd90d4138100140100d0150ef 100644 (file)
@@ -124,7 +124,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C
        /*
         * lookup the local servers Replication Epoch
         */
-       ntds_dn = samdb_ntds_settings_dn(b_state->sam_ctx);
+       ntds_dn = samdb_ntds_settings_dn(b_state->sam_ctx, mem_ctx);
        W_ERROR_HAVE_NO_MEMORY(ntds_dn);
 
        ret = ldb_search(b_state->sam_ctx, mem_ctx, &ntds_res,
index 07e64d321de4a1539eb6b6cdb2ca79585d9488b6..22ff6142ebfcaf9a70c5c2a6e9760f55407854d4 100644 (file)
@@ -723,7 +723,7 @@ static WERROR getncchanges_rid_alloc(struct drsuapi_bind_state *b_state,
                return WERR_DS_DRA_INTERNAL_ERROR;
        }
 
-       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {
+       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb, mem_ctx), fsmo_role_dn) != 0) {
                /* we're not the RID Manager - go away */
                DEBUG(0,(__location__ ": RID Alloc request when not RID Manager\n"));
                ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER;
@@ -1064,7 +1064,7 @@ static WERROR getncchanges_change_master(struct drsuapi_bind_state *b_state,
                return WERR_DS_DRA_INTERNAL_ERROR;
        }
 
-       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {
+       if (ldb_dn_compare(samdb_ntds_settings_dn(ldb, mem_ctx), fsmo_role_dn) != 0) {
                /* we're not the current owner - go away */
                DEBUG(0,(__location__ ": FSMO transfer request when not owner\n"));
                ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER;