mirror of
https://github.com/samba-team/samba.git
synced 2025-01-18 06:04:06 +03:00
CVE-2016-0771: s4:dns_server: fix idl for dns_txt_record
From RFC 1035: 3.3.14. TXT RDATA format +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ / TXT-DATA / +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ where: TXT-DATA One or more <character-string>s. TXT RRs are used to hold descriptive text. The semantics of the text depends on the domain where it is found. Each record contains an array of strings instead of just one string. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11128 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11686 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Garming Sam <garming@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
7693d683b5
commit
df431a39e4
@ -8,7 +8,7 @@
|
||||
encoding if it doesn't work out
|
||||
*/
|
||||
|
||||
import "misc.idl";
|
||||
import "misc.idl", "dnsp.idl";
|
||||
[
|
||||
helper("librpc/ndr/ndr_dns.h"),
|
||||
helpstring("DNS records"),
|
||||
@ -163,9 +163,8 @@ interface dns
|
||||
dns_string exchange;
|
||||
} dns_mx_record;
|
||||
|
||||
typedef [public] struct {
|
||||
[value(strlen(txt))] uint8 length;
|
||||
[charset(DOS)] uint8 txt[length];
|
||||
typedef [public,nopull] struct {
|
||||
dnsp_string_list txt;
|
||||
} dns_txt_record;
|
||||
|
||||
typedef [public] struct {
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "includes.h"
|
||||
#include "librpc/gen_ndr/ndr_dns.h"
|
||||
#include "librpc/gen_ndr/ndr_misc.h"
|
||||
#include "librpc/gen_ndr/ndr_dnsp.h"
|
||||
#include "system/locale.h"
|
||||
#include "lib/util/util_net.h"
|
||||
|
||||
@ -230,6 +231,29 @@ _PUBLIC_ enum ndr_err_code ndr_push_dns_string(struct ndr_push *ndr,
|
||||
return ndr_push_bytes(ndr, (const uint8_t *)"", 1);
|
||||
}
|
||||
|
||||
_PUBLIC_ enum ndr_err_code ndr_pull_dns_txt_record(struct ndr_pull *ndr, int ndr_flags, struct dns_txt_record *r)
|
||||
{
|
||||
NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
enum ndr_err_code ndr_err;
|
||||
uint32_t data_size = ndr->data_size;
|
||||
uint32_t record_size = 0;
|
||||
ndr_err = ndr_token_retrieve(&ndr->array_size_list, r,
|
||||
&record_size);
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
NDR_PULL_NEED_BYTES(ndr, record_size);
|
||||
ndr->data_size = ndr->offset + record_size;
|
||||
}
|
||||
NDR_CHECK(ndr_pull_align(ndr, 1));
|
||||
NDR_CHECK(ndr_pull_dnsp_string_list(ndr, NDR_SCALARS, &r->txt));
|
||||
NDR_CHECK(ndr_pull_trailer_align(ndr, 1));
|
||||
ndr->data_size = data_size;
|
||||
}
|
||||
if (ndr_flags & NDR_BUFFERS) {
|
||||
}
|
||||
return NDR_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
_PUBLIC_ enum ndr_err_code ndr_push_dns_res_rec(struct ndr_push *ndr,
|
||||
int ndr_flags,
|
||||
const struct dns_res_rec *r)
|
||||
@ -302,6 +326,9 @@ _PUBLIC_ enum ndr_err_code ndr_pull_dns_res_rec(struct ndr_pull *ndr,
|
||||
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->length));
|
||||
_saved_offset1 = ndr->offset;
|
||||
if (r->length > 0) {
|
||||
NDR_CHECK(ndr_token_store(ndr, &ndr->array_size_list,
|
||||
&r->rdata,
|
||||
r->length));
|
||||
NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->rdata,
|
||||
r->rr_type));
|
||||
NDR_CHECK(ndr_pull_dns_rdata(ndr, NDR_SCALARS,
|
||||
|
@ -32,7 +32,7 @@ bld.SAMBA_SUBSYSTEM('NDR_DNSSERVER',
|
||||
|
||||
bld.SAMBA_SUBSYSTEM('NDR_DNS',
|
||||
source='gen_ndr/ndr_dns.c ndr/ndr_dns.c',
|
||||
public_deps='ndr'
|
||||
public_deps='ndr NDR_DNSP'
|
||||
)
|
||||
|
||||
bld.SAMBA_SUBSYSTEM('NDR_DSBACKUP',
|
||||
|
@ -46,8 +46,7 @@ static WERROR create_response_rr(const struct dns_name_question *question,
|
||||
{
|
||||
struct dns_res_rec *ans = *answers;
|
||||
uint16_t ai = *ancount;
|
||||
char *tmp;
|
||||
uint32_t i;
|
||||
enum ndr_err_code ndr_err;
|
||||
|
||||
ZERO_STRUCT(ans[ai]);
|
||||
|
||||
@ -101,14 +100,12 @@ static WERROR create_response_rr(const struct dns_name_question *question,
|
||||
}
|
||||
break;
|
||||
case DNS_QTYPE_TXT:
|
||||
tmp = talloc_asprintf(ans, "\"%s\"", rec->data.txt.str[0]);
|
||||
W_ERROR_HAVE_NO_MEMORY(tmp);
|
||||
for (i=1; i<rec->data.txt.count; i++) {
|
||||
tmp = talloc_asprintf_append_buffer(
|
||||
tmp, " \"%s\"", rec->data.txt.str[i]);
|
||||
W_ERROR_HAVE_NO_MEMORY(tmp);
|
||||
ndr_err = ndr_dnsp_string_list_copy(ans,
|
||||
&rec->data.txt,
|
||||
&ans[ai].rdata.txt_record.txt);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
return WERR_NOMEM;
|
||||
}
|
||||
ans[ai].rdata.txt_record.txt = tmp;
|
||||
break;
|
||||
default:
|
||||
DEBUG(0, ("Got unhandled type %u query.\n", rec->wType));
|
||||
|
@ -299,9 +299,7 @@ static WERROR dns_rr_to_dnsp(TALLOC_CTX *mem_ctx,
|
||||
const struct dns_res_rec *rrec,
|
||||
struct dnsp_DnssrvRpcRecord *r)
|
||||
{
|
||||
char *tmp;
|
||||
char *txt_record_txt;
|
||||
char *saveptr = NULL;
|
||||
enum ndr_err_code ndr_err;
|
||||
|
||||
if (rrec->rr_type == DNS_QTYPE_ALL) {
|
||||
return DNS_ERR(FORMAT_ERROR);
|
||||
@ -354,28 +352,11 @@ static WERROR dns_rr_to_dnsp(TALLOC_CTX *mem_ctx,
|
||||
W_ERROR_HAVE_NO_MEMORY(r->data.mx.nameTarget);
|
||||
break;
|
||||
case DNS_QTYPE_TXT:
|
||||
r->data.txt.count = 0;
|
||||
r->data.txt.str = talloc_array(mem_ctx, const char *,
|
||||
r->data.txt.count);
|
||||
W_ERROR_HAVE_NO_MEMORY(r->data.txt.str);
|
||||
|
||||
txt_record_txt = talloc_strdup(r->data.txt.str,
|
||||
rrec->rdata.txt_record.txt);
|
||||
W_ERROR_HAVE_NO_MEMORY(txt_record_txt);
|
||||
|
||||
tmp = strtok_r(txt_record_txt, "\"", &saveptr);
|
||||
while (tmp) {
|
||||
if (strcmp(tmp, " ") == 0) {
|
||||
tmp = strtok_r(NULL, "\"", &saveptr);
|
||||
continue;
|
||||
}
|
||||
r->data.txt.str = talloc_realloc(mem_ctx, r->data.txt.str, const char *,
|
||||
r->data.txt.count+1);
|
||||
r->data.txt.str[r->data.txt.count] = talloc_strdup(r->data.txt.str, tmp);
|
||||
W_ERROR_HAVE_NO_MEMORY(r->data.txt.str[r->data.txt.count]);
|
||||
|
||||
r->data.txt.count++;
|
||||
tmp = strtok_r(NULL, "\"", &saveptr);
|
||||
ndr_err = ndr_dnsp_string_list_copy(mem_ctx,
|
||||
&rrec->rdata.txt_record.txt,
|
||||
&r->data.txt);
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
|
||||
return WERR_NOMEM;
|
||||
}
|
||||
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user