diff options
author | Andrew Bartlett <abartlet@samba.org> | 2012-08-14 16:08:47 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2012-08-14 10:05:14 +0200 |
commit | 956678685325a79a315f4ef19c0d834fd1747e4c (patch) | |
tree | 62b89848fbf552187a07d1d520702112f3b4ac45 | |
parent | 0f2a87b547be43b4764c48350fd03ff22e086806 (diff) | |
download | samba-956678685325a79a315f4ef19c0d834fd1747e4c.tar.gz samba-956678685325a79a315f4ef19c0d834fd1747e4c.tar.bz2 samba-956678685325a79a315f4ef19c0d834fd1747e4c.zip |
s4-dsdb: Add mem_ctx argument to samdb_ntds_settings_dn
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
-rw-r--r-- | source4/dsdb/common/util.c | 28 | ||||
-rw-r--r-- | source4/dsdb/kcc/kcc_connection.c | 4 | ||||
-rw-r--r-- | source4/dsdb/kcc/kcc_periodic.c | 2 | ||||
-rw-r--r-- | source4/dsdb/kcc/kcc_topology.c | 2 | ||||
-rw-r--r-- | source4/dsdb/repl/drepl_fsmo.c | 8 | ||||
-rw-r--r-- | source4/dsdb/repl/drepl_partitions.c | 2 | ||||
-rw-r--r-- | source4/dsdb/repl/drepl_ridalloc.c | 4 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/objectclass.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/ridalloc.c | 4 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/rootdse.c | 4 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/util.c | 7 | ||||
-rw-r--r-- | source4/dsdb/schema/schema_init.c | 2 | ||||
-rw-r--r-- | source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 2 | ||||
-rw-r--r-- | source4/rpc_server/drsuapi/getncchanges.c | 4 |
14 files changed, 45 insertions, 30 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index dca7a4409e..251e17759b 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -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; } diff --git a/source4/dsdb/kcc/kcc_connection.c b/source4/dsdb/kcc/kcc_connection.c index 266f753c37..ea6383342c 100644 --- a/source4/dsdb/kcc/kcc_connection.c +++ b/source4/dsdb/kcc/kcc_connection.c @@ -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); diff --git a/source4/dsdb/kcc/kcc_periodic.c b/source4/dsdb/kcc/kcc_periodic.c index e3792300de..f96347f423 100644 --- a/source4/dsdb/kcc/kcc_periodic.c +++ b/source4/dsdb/kcc/kcc_periodic.c @@ -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); diff --git a/source4/dsdb/kcc/kcc_topology.c b/source4/dsdb/kcc/kcc_topology.c index 9697ec12f7..2a9f2dd15c 100644 --- a/source4/dsdb/kcc/kcc_topology.c +++ b/source4/dsdb/kcc/kcc_topology.c @@ -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")); diff --git a/source4/dsdb/repl/drepl_fsmo.c b/source4/dsdb/repl/drepl_fsmo.c index db6385315b..4a1d08ac1b 100644 --- a/source4/dsdb/repl/drepl_fsmo.c +++ b/source4/dsdb/repl/drepl_fsmo.c @@ -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; } diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c index 3aa715a92d..7464dc1554 100644 --- a/source4/dsdb/repl/drepl_partitions.c +++ b/source4/dsdb/repl/drepl_partitions.c @@ -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); diff --git a/source4/dsdb/repl/drepl_ridalloc.c b/source4/dsdb/repl/drepl_ridalloc.c index 6dcd9efd8a..c817c319f2 100644 --- a/source4/dsdb/repl/drepl_ridalloc.c +++ b/source4/dsdb/repl/drepl_ridalloc.c @@ -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); diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index d431367b5a..7d34b4e8c3 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -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; diff --git a/source4/dsdb/samdb/ldb_modules/ridalloc.c b/source4/dsdb/samdb/ldb_modules/ridalloc.c index 2cef1c445f..915248c440 100644 --- a/source4/dsdb/samdb/ldb_modules/ridalloc.c +++ b/source4/dsdb/samdb/ldb_modules/ridalloc.c @@ -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); diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 6859d04e59..9ae5b20eb1 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -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"); diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c index 0f1a61236f..253d5c1d2c 100644 --- a/source4/dsdb/samdb/ldb_modules/util.c +++ b/source4/dsdb/samdb/ldb_modules/util.c @@ -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, diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index 1771b267cd..8385ac2def 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -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; diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index b170ec3e23..1d51ce879a 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -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, diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 07e64d321d..22ff6142eb 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -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; |