diff options
author | Kai Blin <kai@samba.org> | 2012-08-31 13:41:19 +0200 |
---|---|---|
committer | Kai Blin <kai@samba.org> | 2012-08-31 22:46:01 +0200 |
commit | c256566aa97e040a9b3007c779b1006d20462ccb (patch) | |
tree | af9c0d5a21bf0fde7d27f704b9308f61e088ae0f /source4/dns_server/dns_query.c | |
parent | e4505fc27bf31dbf922635fac19ea52a2a002bd4 (diff) | |
download | samba-c256566aa97e040a9b3007c779b1006d20462ccb.tar.gz samba-c256566aa97e040a9b3007c779b1006d20462ccb.tar.bz2 samba-c256566aa97e040a9b3007c779b1006d20462ccb.zip |
s4 dns: Store TKEYs in a ringbuffer
This stops us from potentially being DoSed by tons of TKEYs
Autobuild-User(master): Kai Blin <kai@samba.org>
Autobuild-Date(master): Fri Aug 31 22:46:01 CEST 2012 on sn-devel-104
Diffstat (limited to 'source4/dns_server/dns_query.c')
-rw-r--r-- | source4/dns_server/dns_query.c | 125 |
1 files changed, 70 insertions, 55 deletions
diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c index e9c3a24b56..530b7b22bd 100644 --- a/source4/dns_server/dns_query.c +++ b/source4/dns_server/dns_query.c @@ -36,7 +36,6 @@ #include "auth/auth.h" #include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" -#include "lib/util/dlinklist.h" static WERROR create_response_rr(const struct dns_name_question *question, const struct dnsp_DnssrvRpcRecord *rec, @@ -321,19 +320,73 @@ static WERROR handle_question(struct dns_server *dns, return WERR_OK; } -static NTSTATUS create_new_tkey(TALLOC_CTX *mem_ctx, - struct dns_server *dns, - struct dns_server_tkey **tkey, - const char* name) +static NTSTATUS accept_gss_ticket(TALLOC_CTX *mem_ctx, + struct dns_server *dns, + struct dns_server_tkey *tkey, + const DATA_BLOB *key, + DATA_BLOB *reply, + uint16_t *dns_auth_error) +{ + NTSTATUS status; + + status = gensec_update(tkey->gensec, mem_ctx, dns->task->event_ctx, + *key, reply); + + if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) { + *dns_auth_error = DNS_RCODE_OK; + return status; + } + + if (NT_STATUS_IS_OK(status)) { + + status = gensec_session_info(tkey->gensec, tkey, &tkey->session_info); + if (!NT_STATUS_IS_OK(status)) { + *dns_auth_error = DNS_RCODE_BADKEY; + return status; + } + *dns_auth_error = DNS_RCODE_OK; + } + + return status; +} + +static struct dns_server_tkey *find_tkey(struct dns_server_tkey_store *store, + const char *name) +{ + struct dns_server_tkey *tkey = NULL; + uint16_t i = 0; + + do { + struct dns_server_tkey *tmp_key = store->tkeys[i]; + + i++; + i %= TKEY_BUFFER_SIZE; + + if (tmp_key == NULL) { + continue; + } + if (dns_name_equal(name, tmp_key->name)) { + tkey = tmp_key; + break; + } + } while (i != 0); + + return tkey; +} + +static NTSTATUS create_tkey(struct dns_server *dns, + const char* name, + struct dns_server_tkey **tkey) { NTSTATUS status; - struct dns_server_tkey *k = talloc_zero(mem_ctx, struct dns_server_tkey); + struct dns_server_tkey_store *store = dns->tkeys; + struct dns_server_tkey *k = talloc_zero(store, struct dns_server_tkey); if (k == NULL) { return NT_STATUS_NO_MEMORY; } - k->name = talloc_strdup(mem_ctx, name); + k->name = talloc_strdup(k, name); if (k->name == NULL) { return NT_STATUS_NO_MEMORY; @@ -363,52 +416,16 @@ static NTSTATUS create_new_tkey(TALLOC_CTX *mem_ctx, return status; } - *tkey = k; - return NT_STATUS_OK; -} - -static NTSTATUS accept_gss_ticket(TALLOC_CTX *mem_ctx, - struct dns_server *dns, - struct dns_server_tkey *tkey, - const DATA_BLOB *key, - DATA_BLOB *reply, - uint16_t *dns_auth_error) -{ - NTSTATUS status; - - status = gensec_update(tkey->gensec, mem_ctx, dns->task->event_ctx, - *key, reply); - - if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) { - *dns_auth_error = DNS_RCODE_OK; - return status; + if (store->tkeys[store->next_idx] != NULL) { + TALLOC_FREE(store->tkeys[store->next_idx]); } - if (NT_STATUS_IS_OK(status)) { + store->tkeys[store->next_idx] = k; + (store->next_idx)++; + store->next_idx %= store->size; - status = gensec_session_info(tkey->gensec, tkey, &tkey->session_info); - if (!NT_STATUS_IS_OK(status)) { - *dns_auth_error = DNS_RCODE_BADKEY; - return status; - } - *dns_auth_error = DNS_RCODE_OK; - } - - return status; -} - -static struct dns_server_tkey *find_tkey(struct dns_server *dns, - const char *name) -{ - struct dns_server_tkey *tkey = NULL; - - for (tkey = dns->tkeys; tkey != NULL; tkey = tkey->next) { - if (dns_name_equal(name, tkey->name)) { - break; - } - } - - return tkey; + *tkey = k; + return NT_STATUS_OK; } static WERROR handle_tkey(struct dns_server *dns, @@ -470,7 +487,7 @@ static WERROR handle_tkey(struct dns_server *dns, DATA_BLOB key; DATA_BLOB reply; - tkey = find_tkey(dns, in->questions[0].name); + tkey = find_tkey(dns->tkeys, in->questions[0].name); if (tkey != NULL && tkey->complete) { /* TODO: check if the key is still valid */ DEBUG(1, ("Rejecting tkey negotiation for already established key\n")); @@ -479,14 +496,12 @@ static WERROR handle_tkey(struct dns_server *dns, } if (tkey == NULL) { - status = create_new_tkey(dns, dns, &tkey, - in->questions[0].name); + status = create_tkey(dns, in->questions[0].name, + &tkey); if (!NT_STATUS_IS_OK(status)) { ret_tkey->rdata.tkey_record.error = DNS_RCODE_BADKEY; return ntstatus_to_werror(status); } - - DLIST_ADD_END(dns->tkeys, tkey, NULL); } key.data = in_tkey->rdata.tkey_record.key_data; |