summaryrefslogtreecommitdiff
path: root/source4/dns_server/dns_query.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2015-08-08 14:36:43 +0200
committerKai Blin <kai@samba.org>2015-12-15 14:43:09 +0100
commit3b7f99e6f4996cfd97220b3a6d5cceeab6ab5b79 (patch)
treeeb066c944753429a7641f388067b663095638be0 /source4/dns_server/dns_query.c
parentb6aaf77897082c6ac447e9514260b435ac3ad854 (diff)
downloadsamba-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.c124
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;