diff options
author | Volker Lendecke <vl@samba.org> | 2015-08-08 14:36:43 +0200 |
---|---|---|
committer | Kai Blin <kai@samba.org> | 2015-12-15 14:43:09 +0100 |
commit | 3b7f99e6f4996cfd97220b3a6d5cceeab6ab5b79 (patch) | |
tree | eb066c944753429a7641f388067b663095638be0 /source4/dns_server/dns_query.c | |
parent | b6aaf77897082c6ac447e9514260b435ac3ad854 (diff) | |
download | samba-3b7f99e6f4996cfd97220b3a6d5cceeab6ab5b79.tar.gz |
dns_server: Add add_dns_res_rec()
Same as add_response_rr(), but it copies over a dns_res_rec
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Kai Blin <kai@samba.org>
Diffstat (limited to 'source4/dns_server/dns_query.c')
-rw-r--r-- | source4/dns_server/dns_query.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/source4/dns_server/dns_query.c b/source4/dns_server/dns_query.c index 128e46b1d09..4e5382582a4 100644 --- a/source4/dns_server/dns_query.c +++ b/source4/dns_server/dns_query.c @@ -140,6 +140,130 @@ static WERROR add_response_rr(const char *name, return WERR_OK; } +static WERROR add_dns_res_rec(struct dns_res_rec **pdst, + const struct dns_res_rec *src) +{ + struct dns_res_rec *dst = *pdst; + uint16_t di = talloc_array_length(dst); + + if (di == UINT16_MAX) { + return WERR_BUFFER_OVERFLOW; + } + + dst = talloc_realloc(dst, dst, struct dns_res_rec, di+1); + if (dst == NULL) { + return WERR_NOMEM; + } + + ZERO_STRUCT(dst[di]); + + dst[di] = (struct dns_res_rec) { + .name = talloc_strdup(dst, src->name), + .rr_type = src->rr_type, + .rr_class = src->rr_class, + .ttl = src->ttl, + .length = src->length + }; + + if (dst[di].name == NULL) { + return WERR_NOMEM; + } + + switch (src->rr_type) { + case DNS_QTYPE_CNAME: + dst[di].rdata.cname_record = talloc_strdup( + dst, src->rdata.cname_record); + if (dst[di].rdata.cname_record == NULL) { + return WERR_NOMEM; + } + break; + case DNS_QTYPE_A: + dst[di].rdata.ipv4_record = talloc_strdup( + dst, src->rdata.ipv4_record); + if (dst[di].rdata.ipv4_record == NULL) { + return WERR_NOMEM; + } + break; + case DNS_QTYPE_AAAA: + dst[di].rdata.ipv6_record = talloc_strdup( + dst, src->rdata.ipv6_record); + if (dst[di].rdata.ipv6_record == NULL) { + return WERR_NOMEM; + } + break; + case DNS_TYPE_NS: + dst[di].rdata.ns_record = talloc_strdup( + dst, src->rdata.ns_record); + if (dst[di].rdata.ns_record == NULL) { + return WERR_NOMEM; + } + break; + case DNS_QTYPE_SRV: + dst[di].rdata.srv_record = (struct dns_srv_record) { + .priority = src->rdata.srv_record.priority, + .weight = src->rdata.srv_record.weight, + .port = src->rdata.srv_record.port, + .target = talloc_strdup( + dst, src->rdata.srv_record.target) + }; + if (dst[di].rdata.srv_record.target == NULL) { + return WERR_NOMEM; + } + break; + case DNS_QTYPE_SOA: + dst[di].rdata.soa_record = (struct dns_soa_record) { + .mname = talloc_strdup( + dst, src->rdata.soa_record.mname), + .rname = talloc_strdup( + dst, src->rdata.soa_record.rname), + .serial = src->rdata.soa_record.serial, + .refresh = src->rdata.soa_record.refresh, + .retry = src->rdata.soa_record.retry, + .expire = src->rdata.soa_record.expire, + .minimum = src->rdata.soa_record.minimum + }; + + if ((dst[di].rdata.soa_record.mname == NULL) || + (dst[di].rdata.soa_record.rname == NULL)) { + return WERR_NOMEM; + } + + break; + case DNS_QTYPE_PTR: + dst[di].rdata.ptr_record = talloc_strdup( + dst, src->rdata.ptr_record); + if (dst[di].rdata.ptr_record == NULL) { + return WERR_NOMEM; + } + break; + case DNS_QTYPE_MX: + dst[di].rdata.mx_record = (struct dns_mx_record) { + .preference = src->rdata.mx_record.preference, + .exchange = talloc_strdup( + src, src->rdata.mx_record.exchange) + }; + + if (dst[di].rdata.mx_record.exchange == NULL) { + return WERR_NOMEM; + } + break; + case DNS_QTYPE_TXT: + dst[di].rdata.txt_record.txt = talloc_strdup( + dst, src->rdata.txt_record.txt); + if (dst[di].rdata.txt_record.txt == NULL) { + return WERR_NOMEM; + } + break; + default: + DBG_WARNING("Got unhandled type %u query.\n", src->rr_type); + return DNS_ERR(NOT_IMPLEMENTED); + } + + *pdst = dst; + + return WERR_OK; +} + struct ask_forwarder_state { struct tevent_context *ev; uint16_t id; |