diff options
author | Amitay Isaacs <amitay@gmail.com> | 2012-05-23 11:52:16 +1000 |
---|---|---|
committer | Amitay Isaacs <amitay@gmail.com> | 2012-05-24 09:42:24 +1000 |
commit | 34eab45cba6989b66d37c7eb74d97846014ec4eb (patch) | |
tree | 615f2a5b9c1e0d41af402009013654b804294865 /source4/dns_server | |
parent | e8601c02ba59fb12b46919a50702365ceee6aee1 (diff) | |
download | samba-34eab45cba6989b66d37c7eb74d97846014ec4eb.tar.gz |
dlz_bind9: Fix the named crash on reloading named
When reloading zones, named first creates new zone instance and then shuts down
the old instance. Since ldb layer, keeps the same LDB open, talloc_free() on samdb
handle, causes talloc "access after use" error.
This patch keeps only single context (dlz_bind9_data) and uses reference counting
to decide when to actually free the context. Since samdb handle is reused, use
talloc_unlink() instead of talloc_free() on samdb handle.
Diffstat (limited to 'source4/dns_server')
-rw-r--r-- | source4/dns_server/dlz_bind9.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c index 224f242b879..4be7aaea83e 100644 --- a/source4/dns_server/dlz_bind9.c +++ b/source4/dns_server/dlz_bind9.c @@ -65,6 +65,8 @@ struct dlz_bind9_data { dns_dlz_writeablezone_t *writeable_zone; }; +static struct dlz_bind9_data *dlz_bind9_state = NULL; +static int dlz_bind9_state_ref_count = 0; static const char *zone_prefixes[] = { "CN=MicrosoftDNS,DC=DomainDnsZones", @@ -570,6 +572,12 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname, struct ldb_dn *dn; NTSTATUS nt_status; + if (dlz_bind9_state != NULL) { + *dbdata = dlz_bind9_state; + dlz_bind9_state_ref_count++; + return ISC_R_SUCCESS; + } + state = talloc_zero(NULL, struct dlz_bind9_data); if (state == NULL) { return ISC_R_NOMEMORY; @@ -664,6 +672,8 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname, state->auth_context->generate_session_info_pac = b9_generate_session_info_pac; *dbdata = state; + dlz_bind9_state = state; + dlz_bind9_state_ref_count++; return ISC_R_SUCCESS; @@ -679,7 +689,13 @@ _PUBLIC_ void dlz_destroy(void *dbdata) { struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data); state->log(ISC_LOG_INFO, "samba_dlz: shutting down"); - talloc_free(state); + + dlz_bind9_state_ref_count--; + if (dlz_bind9_state_ref_count == 0) { + talloc_unlink(state, state->samdb); + talloc_free(state); + dlz_bind9_state = NULL; + } } |