]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib/addns: Use NDR marshalling for signed DNS updates
authorVolker Lendecke <vl@samba.org>
Thu, 14 May 2026 08:14:58 +0000 (10:14 +0200)
committerVolker Lendecke <vl@samba.org>
Fri, 3 Jul 2026 08:08:36 +0000 (08:08 +0000)
This together with the previous patch removes a lot of code depending
on the hand-marshalling in lib/addns. Overall it's about 50 lines code
less, but it will make it possible to remove more code.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
lib/addns/dns.h
lib/addns/dnsgss.c
lib/addns/dnsmarshall.c
lib/addns/dnsrecord.c
source3/utils/net_ads_join_dns.c
source3/utils/net_dns.c

index 91e4568eb570255622d8ecc0cf5dce1e8fb8f279..72fc08eb542cc9dd17ad090745425801b47e0ec2 100644 (file)
@@ -83,16 +83,6 @@ MX              15 mail exchange
 TXT             16 text strings
 */
 
-/*
- * TKEY Modes from rfc2930
- */
-
-#define DNS_TKEY_MODE_SERVER   1
-#define DNS_TKEY_MODE_DH       2
-#define DNS_TKEY_MODE_GSSAPI   3
-#define DNS_TKEY_MODE_RESOLVER 4
-#define DNS_TKEY_MODE_DELETE   5
-
 #define  DNS_NO_ERROR          0
 #define  DNS_FORMAT_ERROR      1
 #define  DNS_SERVER_FAILURE    2
@@ -139,16 +129,6 @@ struct dns_rrec {
        uint8_t *data;
 };
 
-struct addns_tkey_record {
-       struct dns_domain_name *algorithm;
-       time_t inception;
-       time_t expiration;
-       uint16_t mode;
-       uint16_t error;
-       uint16_t key_length;
-       uint8_t *key;
-};
-
 struct dns_request {
        uint16_t id;
        uint16_t flags;
@@ -208,42 +188,18 @@ DNS_ERROR dns_create_query( TALLOC_CTX *mem_ctx, const char *name,
                            struct dns_request **preq );
 DNS_ERROR dns_create_update( TALLOC_CTX *mem_ctx, const char *name,
                             struct dns_update_request **preq );
-DNS_ERROR dns_create_probe(TALLOC_CTX *mem_ctx, const char *zone,
-                          const char *host, int num_ips,
-                          const struct sockaddr_storage *sslist,
-                          struct dns_update_request **preq);
 DNS_ERROR dns_create_rrec(TALLOC_CTX *mem_ctx, const char *name,
                          uint16_t type, uint16_t r_class, uint32_t ttl,
                          uint16_t data_length, uint8_t *data,
                          struct dns_rrec **prec);
 DNS_ERROR dns_add_rrec(TALLOC_CTX *mem_ctx, struct dns_rrec *rec,
                       uint16_t *num_records, struct dns_rrec ***records);
-DNS_ERROR dns_create_tkey_record(TALLOC_CTX *mem_ctx, const char *keyname,
-                                const char *algorithm_name, time_t inception,
-                                time_t expiration, uint16_t mode, uint16_t error,
-                                uint16_t key_length, const uint8_t *key,
-                                struct dns_rrec **prec);
 DNS_ERROR dns_create_a_record(TALLOC_CTX *mem_ctx, const char *host,
                              uint32_t ttl, const struct sockaddr_storage *pss,
                              struct dns_rrec **prec);
 DNS_ERROR dns_create_aaaa_record(TALLOC_CTX *mem_ctx, const char *host,
                                 uint32_t ttl, const struct sockaddr_storage *pss,
                                 struct dns_rrec **prec);
-DNS_ERROR dns_unmarshall_tkey_record(TALLOC_CTX *mem_ctx, struct dns_rrec *rec,
-                                    struct addns_tkey_record **ptkey);
-DNS_ERROR dns_create_tsig_record(TALLOC_CTX *mem_ctx, const char *keyname,
-                                const char *algorithm_name,
-                                time_t time_signed, uint16_t fudge,
-                                uint16_t mac_length, const uint8_t *mac,
-                                uint16_t original_id, uint16_t error,
-                                struct dns_rrec **prec);
-DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
-                                   const char *domainname,
-                                   const char *hostname,
-                                   const struct sockaddr_storage *ip_addr,
-                                   size_t num_adds,
-                                   uint32_t ttl,
-                                   struct dns_update_request **preq);
 
 /* from dnssock.c */
 
@@ -289,9 +245,6 @@ DNS_ERROR dns_unmarshall_request(TALLOC_CTX *mem_ctx,
 DNS_ERROR dns_marshall_update_request(TALLOC_CTX *mem_ctx,
                                      struct dns_update_request *update,
                                      struct dns_buffer **pbuf);
-DNS_ERROR dns_unmarshall_update_request(TALLOC_CTX *mem_ctx,
-                                       struct dns_buffer *buf,
-                                       struct dns_update_request **pupreq);
 struct dns_request *dns_update2request(struct dns_update_request *update);
 struct dns_update_request *dns_request2update(struct dns_request *request);
 uint16_t dns_response_code(uint16_t flags);
@@ -305,10 +258,5 @@ DNS_ERROR dns_negotiate_sec_ctx(const char *serveraddress,
                                const char *keyname,
                                struct gensec_security *gensec,
                                enum dns_ServerType srv_type);
-DNS_ERROR dns_sign_update(struct dns_update_request *req,
-                         struct gensec_security *gensec,
-                         const char *keyname,
-                         const char *algorithmname,
-                         time_t time_signed, uint16_t fudge);
 
 #endif /* _DNS_H */
index 71411430ce991b80811d0f6e04b1d8fa06154a7e..c121e30e236379a898c439d1a282bc1bc423c367 100644 (file)
 #include "lib/util/charset/charset.h"
 #include "libcli/util/ntstatus.h"
 #include "auth/gensec/gensec.h"
-
+#include "dnserr.h"
+#include "librpc/gen_ndr/dns.h"
 #include "dns.h"
+#include "libcli/dns/libdns.h"
 
-static DNS_ERROR dns_negotiate_gss_ctx_int(struct dns_connection *conn,
-                                          const char *keyname,
-                                          struct gensec_security *gensec,
-                                          enum dns_ServerType srv_type)
+DNS_ERROR dns_negotiate_sec_ctx(const char *serveraddress,
+                               const char *keyname,
+                               struct gensec_security *gensec,
+                               enum dns_ServerType srv_type)
 {
        TALLOC_CTX *frame = talloc_stackframe();
-       struct dns_request *req = NULL;
-       struct dns_buffer *buf = NULL;
+       struct dns_name_packet *reply = NULL;
        DATA_BLOB in = { .length = 0, };
        DATA_BLOB out = { .length = 0, };
        NTSTATUS status;
@@ -48,93 +49,88 @@ static DNS_ERROR dns_negotiate_gss_ctx_int(struct dns_connection *conn,
 
        do {
                status = gensec_update(gensec, frame, in, &out);
-               data_blob_free(&in);
+               TALLOC_FREE(reply);
                if (GENSEC_UPDATE_IS_NTERROR(status)) {
                        err = ERROR_DNS_GSS_ERROR;
                        goto error;
                }
 
                if (out.length != 0) {
-                       struct dns_rrec *rec;
-
+                       int ret;
                        time_t t = time(NULL);
 
-                       err = dns_create_query(frame, keyname, QTYPE_TKEY,
-                                              DNS_CLASS_IN, &req);
-                       if (!ERR_DNS_IS_OK(err)) goto error;
-
-                       err = dns_create_tkey_record(
-                               req, keyname, "gss.microsoft.com", t,
-                               t + 86400, DNS_TKEY_MODE_GSSAPI, 0,
-                               out.length, out.data,
-                               &rec );
-                       if (!ERR_DNS_IS_OK(err)) goto error;
+                       struct dns_res_rec tkey = {
+                               .name = keyname,
+                               .rr_type = QTYPE_TKEY,
+                               .rr_class = DNS_CLASS_ANY,
+                               .length = 1,
+                               .rdata.tkey_record
+                                       .algorithm = "gss.microsoft.com",
+                               .rdata.tkey_record.inception = t,
+                               .rdata.tkey_record.expiration = t + 86400,
+                               .rdata.tkey_record.mode = DNS_TKEY_MODE_GSSAPI,
+                               .rdata.tkey_record.key_size = out.length,
+                               .rdata.tkey_record.key_data = out.data,
+                       };
+                       struct dns_name_question question = {
+                               .name = keyname,
+                               .question_class = DNS_CLASS_IN,
+                               .question_type = QTYPE_TKEY,
+                       };
+                       struct dns_name_packet rec = {
+                               .operation = DNS_OPCODE_QUERY,
+                               .qdcount = 1,
+                               .questions = &question,
+                       };
 
                        /* Windows 2000 DNS is broken and requires the
                           TKEY payload in the Answer section instead
                           of the Additional section like Windows 2003 */
 
                        if ( srv_type == DNS_SRV_WIN2000 ) {
-                               err = dns_add_rrec(req, rec, &req->num_answers,
-                                                  &req->answers);
+                               rec.ancount = 1;
+                               rec.answers = &tkey;
                        } else {
-                               err = dns_add_rrec(req, rec, &req->num_additionals,
-                                                  &req->additional);
+                               rec.arcount = 1;
+                               rec.additional = &tkey;
                        }
-                       
-                       if (!ERR_DNS_IS_OK(err)) goto error;
-
-                       err = dns_marshall_request(frame, req, &buf);
-                       if (!ERR_DNS_IS_OK(err)) goto error;
-
-                       err = dns_send(conn, buf);
-                       if (!ERR_DNS_IS_OK(err)) goto error;
 
-                       TALLOC_FREE(buf);
-                       TALLOC_FREE(req);
-
-                       err = dns_receive(frame, conn, &buf);
-                       if (!ERR_DNS_IS_OK(err)) goto error;
+                       ret = dns_cli_request(frame,
+                                             serveraddress,
+                                             &rec,
+                                             &reply);
+                       if (ret != 0) {
+                               err = ERROR_DNS_SOCKET_ERROR;
+                               goto error;
+                       }
                }
 
                if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-                       struct dns_request *resp;
-                       struct addns_tkey_record *tkey;
-                       struct dns_rrec *tkey_answer = NULL;
-                       uint16_t i;
-
-                       if (buf == NULL) {
-                               err = ERROR_DNS_BAD_RESPONSE;
-                               goto error;
-                       }
+                       struct dns_res_rec *tkey_answer = NULL;
+                       struct dns_tkey_record *tkey = NULL;
 
-                       err = dns_unmarshall_request(buf, buf, &resp);
-                       if (!ERR_DNS_IS_OK(err)) goto error;
+                       uint16_t i;
 
                        /*
                         * TODO: Compare id and keyname
                         */
 
-                       for (i=0; i < resp->num_answers; i++) {
-                               if (resp->answers[i]->type != QTYPE_TKEY) {
-                                       continue;
-                               }
+                       for (i = 0; i < reply->ancount; i++) {
+                               tkey_answer = &reply->answers[i];
 
-                               tkey_answer = resp->answers[i];
+                               if (tkey_answer->rr_type == QTYPE_TKEY) {
+                                       break;
+                               }
                        }
 
-                       if (tkey_answer == NULL) {
+                       if (i == reply->ancount) {
                                err = ERROR_DNS_INVALID_MESSAGE;
                                goto error;
                        }
 
-                       err = dns_unmarshall_tkey_record(
-                               frame, resp->answers[0], &tkey);
-                       if (!ERR_DNS_IS_OK(err)) goto error;
-
-                       in = data_blob_const(tkey->key, tkey->key_length);
+                       tkey = &tkey_answer->rdata.tkey_record;
 
-                       TALLOC_FREE(buf);
+                       in = data_blob_const(tkey->key_data, tkey->key_size);
                }
 
        } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED));
@@ -148,91 +144,3 @@ static DNS_ERROR dns_negotiate_gss_ctx_int(struct dns_connection *conn,
        TALLOC_FREE(frame);
        return err;
 }
-
-DNS_ERROR dns_negotiate_sec_ctx(const char *serveraddress,
-                               const char *keyname,
-                               struct gensec_security *gensec,
-                               enum dns_ServerType srv_type)
-{
-       TALLOC_CTX *frame = talloc_stackframe();
-       DNS_ERROR err;
-       struct dns_connection *conn = NULL;
-
-       err = dns_open_connection(serveraddress, DNS_TCP, frame, &conn);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       err = dns_negotiate_gss_ctx_int(conn, keyname,
-                                       gensec,
-                                       srv_type);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
- error:
-       TALLOC_FREE(frame);
-
-       return err;
-}
-
-DNS_ERROR dns_sign_update(struct dns_update_request *req,
-                         struct gensec_security *gensec,
-                         const char *keyname,
-                         const char *algorithmname,
-                         time_t time_signed, uint16_t fudge)
-{
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct dns_buffer *buf;
-       DNS_ERROR err;
-       struct dns_domain_name *key, *algorithm;
-       struct dns_rrec *rec;
-       DATA_BLOB mic = { .length = 0, };
-       NTSTATUS status;
-
-       err = dns_marshall_update_request(frame, req, &buf);
-       if (!ERR_DNS_IS_OK(err)) return err;
-
-       err = dns_domain_name_from_string(frame, keyname, &key);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       err = dns_domain_name_from_string(frame, algorithmname, &algorithm);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       dns_marshall_domain_name(buf, key);
-       dns_marshall_uint16(buf, DNS_CLASS_ANY);
-       dns_marshall_uint32(buf, 0); /* TTL */
-       dns_marshall_domain_name(buf, algorithm);
-       dns_marshall_uint16(buf, 0); /* Time prefix for 48-bit time_t */
-       dns_marshall_uint32(buf, time_signed);
-       dns_marshall_uint16(buf, fudge);
-       dns_marshall_uint16(buf, 0); /* error */
-       dns_marshall_uint16(buf, 0); /* other len */
-
-       err = buf->error;
-       if (!ERR_DNS_IS_OK(buf->error)) goto error;
-
-       status = gensec_sign_packet(gensec,
-                                   frame,
-                                   buf->data,
-                                   buf->offset,
-                                   buf->data,
-                                   buf->offset,
-                                   &mic);
-       if (!NT_STATUS_IS_OK(status)) {
-               err = ERROR_DNS_GSS_ERROR;
-               goto error;
-       }
-
-       if (mic.length > 0xffff) {
-               err = ERROR_DNS_GSS_ERROR;
-               goto error;
-       }
-
-       err = dns_create_tsig_record(frame, keyname, algorithmname, time_signed,
-                                    fudge, mic.length, mic.data,
-                                    req->id, 0, &rec);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       err = dns_add_rrec(req, rec, &req->num_additionals, &req->additional);
-
- error:
-       TALLOC_FREE(frame);
-       return err;
-}
index c95420304f07fe004e5d8ad9a25227bbea6bad53..f68d875cc0a959b2f288cf77a63f1622e8035e3d 100644 (file)
@@ -515,19 +515,6 @@ DNS_ERROR dns_marshall_update_request(TALLOC_CTX *mem_ctx,
        return dns_marshall_request(mem_ctx, dns_update2request(update), pbuf);
 }
 
-DNS_ERROR dns_unmarshall_update_request(TALLOC_CTX *mem_ctx,
-                                       struct dns_buffer *buf,
-                                       struct dns_update_request **pupreq)
-{
-       /*
-        * See comments above about portability. If the above works, this will
-        * as well.
-        */
-
-       return dns_unmarshall_request(mem_ctx, buf,
-                                     (struct dns_request **)(void *)pupreq);
-}
-
 uint16_t dns_response_code(uint16_t flags)
 {
        return flags & 0xF;
index 47d1ed0458fa0f2b771bd953ec198c3b874a4cff..d8a29453f177682bdf2247b328cd2f092a8979f7 100644 (file)
@@ -179,175 +179,6 @@ DNS_ERROR dns_create_aaaa_record(TALLOC_CTX *mem_ctx, const char *host,
 #endif
 }
 
-static DNS_ERROR dns_create_name_in_use_record(
-       TALLOC_CTX *mem_ctx,
-       const char *name,
-       const struct sockaddr_storage *ss,
-       struct dns_rrec **prec)
-{
-       if (ss != NULL) {
-               switch (ss->ss_family) {
-               case AF_INET:
-                       return dns_create_a_record(mem_ctx, name, 0, ss, prec);
-#ifdef HAVE_IPV6
-               case AF_INET6:
-                       return dns_create_aaaa_record(mem_ctx, name, 0, ss, prec);
-#endif
-               default:
-                       return ERROR_DNS_INVALID_PARAMETER;
-               }
-       }
-
-       return dns_create_rrec(mem_ctx, name, QTYPE_ANY, DNS_CLASS_IN, 0, 0,
-                              NULL, prec);
-}
-
-static DNS_ERROR dns_create_name_not_in_use_record(TALLOC_CTX *mem_ctx,
-                                                  const char *name,
-                                                  uint32_t type,
-                                                  struct dns_rrec **prec)
-{
-       return dns_create_rrec(mem_ctx, name, type, DNS_CLASS_NONE, 0,
-                              0, NULL, prec);
-}
-
-static DNS_ERROR dns_create_delete_record(TALLOC_CTX *mem_ctx,
-                                         const char *name,
-                                         uint16_t type,
-                                         uint16_t r_class,
-                                         struct dns_rrec **prec)
-{
-       return dns_create_rrec(mem_ctx, name, type, r_class, 0, 0, NULL, prec);
-}
-
-DNS_ERROR dns_create_tkey_record(TALLOC_CTX *mem_ctx, const char *keyname,
-                                const char *algorithm_name, time_t inception,
-                                time_t expiration, uint16_t mode, uint16_t error,
-                                uint16_t key_length, const uint8_t *key,
-                                struct dns_rrec **prec)
-{
-       struct dns_buffer *buf = NULL;
-       struct dns_domain_name *algorithm = NULL;
-       DNS_ERROR err;
-
-       if (!(buf = dns_create_buffer(mem_ctx))) {
-               return ERROR_DNS_NO_MEMORY;
-       }
-
-       err = dns_domain_name_from_string(buf, algorithm_name, &algorithm);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       dns_marshall_domain_name(buf, algorithm);
-       dns_marshall_uint32(buf, inception);
-       dns_marshall_uint32(buf, expiration);
-       dns_marshall_uint16(buf, mode);
-       dns_marshall_uint16(buf, error);
-       dns_marshall_uint16(buf, key_length);
-       dns_marshall_buffer(buf, key, key_length);
-       dns_marshall_uint16(buf, 0); /* Other Size */
-
-       if (!ERR_DNS_IS_OK(buf->error)) {
-               err = buf->error;
-               goto error;
-       }
-
-       err = dns_create_rrec(mem_ctx, keyname, QTYPE_TKEY, DNS_CLASS_ANY, 0,
-                             buf->offset, buf->data, prec);
-
- error:
-       TALLOC_FREE(buf);
-       return err;
-}
-
-DNS_ERROR dns_unmarshall_tkey_record(TALLOC_CTX *mem_ctx, struct dns_rrec *rec,
-                                    struct addns_tkey_record **ptkey)
-{
-       struct addns_tkey_record *tkey;
-       struct dns_buffer buf;
-       uint32_t tmp_inception, tmp_expiration;
-       
-       if (!(tkey = talloc(mem_ctx, struct addns_tkey_record))) {
-               return ERROR_DNS_NO_MEMORY;
-       }
-
-       buf.data = rec->data;
-       buf.size = rec->data_length;
-       buf.offset = 0;
-       buf.error = ERROR_DNS_SUCCESS;
-
-       dns_unmarshall_domain_name(tkey, &buf, &tkey->algorithm);
-       dns_unmarshall_uint32(&buf, &tmp_inception);
-       dns_unmarshall_uint32(&buf, &tmp_expiration);
-       dns_unmarshall_uint16(&buf, &tkey->mode);
-       dns_unmarshall_uint16(&buf, &tkey->error);
-       dns_unmarshall_uint16(&buf, &tkey->key_length);
-
-       if (!ERR_DNS_IS_OK(buf.error)) goto error;
-
-       if (tkey->key_length) {
-               if (!(tkey->key = talloc_array(tkey, uint8_t, tkey->key_length))) {
-                       buf.error = ERROR_DNS_NO_MEMORY;
-                       goto error;
-               }
-       } else {
-               tkey->key = NULL;
-       }
-
-       dns_unmarshall_buffer(&buf, tkey->key, tkey->key_length);
-       if (!ERR_DNS_IS_OK(buf.error)) goto error;
-
-       tkey->inception = (time_t)tmp_inception;
-       tkey->expiration = (time_t)tmp_expiration;
-
-       *ptkey = tkey;
-       return ERROR_DNS_SUCCESS;
-
- error:
-       TALLOC_FREE(tkey);
-       return buf.error;
-}
-
-DNS_ERROR dns_create_tsig_record(TALLOC_CTX *mem_ctx, const char *keyname,
-                                const char *algorithm_name,
-                                time_t time_signed, uint16_t fudge,
-                                uint16_t mac_length, const uint8_t *mac,
-                                uint16_t original_id, uint16_t error,
-                                struct dns_rrec **prec)
-{
-       struct dns_buffer *buf = NULL;
-       struct dns_domain_name *algorithm = NULL;
-       DNS_ERROR err;
-
-       if (!(buf = dns_create_buffer(mem_ctx))) {
-               return ERROR_DNS_NO_MEMORY;
-       }
-
-       err = dns_domain_name_from_string(buf, algorithm_name, &algorithm);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       dns_marshall_domain_name(buf, algorithm);
-       dns_marshall_uint16(buf, 0); /* time prefix */
-       dns_marshall_uint32(buf, time_signed);
-       dns_marshall_uint16(buf, fudge);
-       dns_marshall_uint16(buf, mac_length);
-       dns_marshall_buffer(buf, mac, mac_length);
-       dns_marshall_uint16(buf, original_id);
-       dns_marshall_uint16(buf, error);
-       dns_marshall_uint16(buf, 0); /* Other Size */
-
-       if (!ERR_DNS_IS_OK(buf->error)) {
-               err = buf->error;
-               goto error;
-       }
-
-       err = dns_create_rrec(mem_ctx, keyname, QTYPE_TSIG, DNS_CLASS_ANY, 0,
-                             buf->offset, buf->data, prec);
-
- error:
-       TALLOC_FREE(buf);
-       return err;
-}
-
 DNS_ERROR dns_add_rrec(TALLOC_CTX *mem_ctx, struct dns_rrec *rec,
                       uint16_t *num_records, struct dns_rrec ***records)
 {
@@ -365,124 +196,3 @@ DNS_ERROR dns_add_rrec(TALLOC_CTX *mem_ctx, struct dns_rrec *rec,
        *records = new_records;
        return ERROR_DNS_SUCCESS;
 }
-
-/*
- * Create a request that probes a server whether the list of IP addresses
- * provides meets our expectations
- */
-
-DNS_ERROR dns_create_probe(TALLOC_CTX *mem_ctx, const char *zone,
-                          const char *host, int num_ips,
-                          const struct sockaddr_storage *sslist,
-                          struct dns_update_request **preq)
-{
-       struct dns_update_request *req = NULL;
-       struct dns_rrec *rec = NULL;
-       DNS_ERROR err;
-       uint16_t i;
-
-       err = dns_create_update(mem_ctx, zone, &req);
-       if (!ERR_DNS_IS_OK(err)) return err;
-
-       err = dns_create_name_not_in_use_record(req, host, QTYPE_CNAME, &rec);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       err = dns_add_rrec(req, rec, &req->num_preqs, &req->preqs);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       for (i=0; i<num_ips; i++) {
-               err = dns_create_name_in_use_record(req, host,
-                                                   &sslist[i], &rec);
-               if (!ERR_DNS_IS_OK(err)) goto error;
-
-               err = dns_add_rrec(req, rec, &req->num_preqs, &req->preqs);
-               if (!ERR_DNS_IS_OK(err)) goto error;
-       }
-
-       *preq = req;
-       return ERROR_DNS_SUCCESS;
-
- error:
-       TALLOC_FREE(req);
-       return err;
-}
-                          
-DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx,
-                                   const char *domainname,
-                                   const char *hostname,
-                                   const struct sockaddr_storage *ss_addrs,
-                                   size_t num_addrs,
-                                   uint32_t ttl,
-                                   struct dns_update_request **preq)
-{
-       struct dns_update_request *req = NULL;
-       struct dns_rrec *rec = NULL;
-       DNS_ERROR err;
-       size_t i;
-
-       err = dns_create_update(mem_ctx, domainname, &req);
-       if (!ERR_DNS_IS_OK(err)) return err;
-
-       /*
-        * Use the same prereq as WinXP -- No CNAME records for this host.
-        */
-
-       err = dns_create_rrec(req, hostname, QTYPE_CNAME, DNS_CLASS_NONE,
-                             0, 0, NULL, &rec);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       err = dns_add_rrec(req, rec, &req->num_preqs, &req->preqs);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       /*
-        * Delete all existing RRsets from our name
-        */
-
-       err = dns_create_delete_record(req, hostname, QTYPE_ANY, DNS_CLASS_ANY,
-                                      &rec);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
-       if (!ERR_DNS_IS_OK(err)) goto error;
-
-       /*
-        * .. and add our IPs
-        */
-
-       for ( i=0; i<num_addrs; i++ ) {
-
-               switch(ss_addrs[i].ss_family) {
-               case AF_INET:
-                       err = dns_create_a_record(req,
-                                                 hostname,
-                                                 ttl,
-                                                 &ss_addrs[i],
-                                                 &rec);
-                       break;
-#ifdef HAVE_IPV6
-               case AF_INET6:
-                       err = dns_create_aaaa_record(req,
-                                                    hostname,
-                                                    ttl,
-                                                    &ss_addrs[i],
-                                                    &rec);
-                       break;
-#endif
-               default:
-                       continue;
-               }
-               if (!ERR_DNS_IS_OK(err))
-                       goto error;
-
-               err = dns_add_rrec(req, rec, &req->num_updates, &req->updates);
-               if (!ERR_DNS_IS_OK(err))
-                       goto error;
-       }
-
-       *preq = req;
-       return ERROR_DNS_SUCCESS;
-
- error:
-       TALLOC_FREE(req);
-       return err;
-}
index a6ea8b4b33eaea899e980ed5b770a25dbc75ef39..86ec5a7a529d67be37634cb99a4bb6d3648cf69f 100644 (file)
@@ -195,7 +195,7 @@ do_update:
                                      dnsdomain,
                                      machine_name,
                                      creds,
-                                     addrs,
+                                     addrs,
                                      num_addrs,
                                      flags,
                                      ttl,
index e6086d8fac6585d66f184855779ed5e344c93ad8..1a8d3e8877f84072bb0a70e77e366eeca2ec8266 100644 (file)
@@ -25,6 +25,7 @@
 #include "utils/net_dns.h"
 #include "auth/gensec/gensec.h"
 #include "auth_generic.h"
+#include "libcli/dns/libdns.h"
 
 #if defined(HAVE_KRB5)
 
@@ -100,7 +101,7 @@ DNS_ERROR DoDNSUpdate(const char *pszServerAddress,
                      const char *pszDomainName,
                      const char *pszHostName,
                      struct cli_credentials *creds,
-                     const struct sockaddr_storage *sslist,
+                     const struct sockaddr_storage *_sslist,
                      size_t num_addrs,
                      uint32_t flags,
                      uint32_t ttl,
@@ -109,7 +110,8 @@ DNS_ERROR DoDNSUpdate(const char *pszServerAddress,
        DNS_ERROR err;
        struct dns_connection *conn;
        TALLOC_CTX *mem_ctx;
-       struct dns_update_request *req, *resp;
+       struct samba_sockaddr sslist[num_addrs];
+       size_t i;
 
        DEBUG(10,("DoDNSUpdate called with flags: 0x%08x\n", flags));
 
@@ -119,7 +121,7 @@ DNS_ERROR DoDNSUpdate(const char *pszServerAddress,
                return ERROR_DNS_INVALID_PARAMETER;
        }
 
-       if ( !remove_host && ((num_addrs <= 0) || !sslist) ) {
+       if (!remove_host && ((num_addrs <= 0) || !_sslist)) {
                return ERROR_DNS_INVALID_PARAMETER;
        }
 
@@ -127,6 +129,10 @@ DNS_ERROR DoDNSUpdate(const char *pszServerAddress,
                return ERROR_DNS_NO_MEMORY;
        }
 
+       for (i = 0; i < num_addrs; i++) {
+               sslist[i] = (struct samba_sockaddr){.u.ss = _sslist[i]};
+       }
+
        err = dns_open_connection(pszServerAddress, DNS_TCP, mem_ctx, &conn);
        if (!ERR_DNS_IS_OK(err)) {
                goto error;
@@ -134,23 +140,31 @@ DNS_ERROR DoDNSUpdate(const char *pszServerAddress,
 
        if (flags & DNS_UPDATE_PROBE) {
 
-               /*
-                * Probe if everything's fine
-                */
-
-               err = dns_create_probe(mem_ctx, pszDomainName, pszHostName,
-                                      num_addrs, sslist, &req);
-               if (!ERR_DNS_IS_OK(err)) goto error;
+               struct dns_name_packet *probe = NULL, *reply = NULL;
+               int ret;
 
-               err = dns_update_transaction(mem_ctx, conn, req, &resp);
+               probe = dns_cli_create_probe(mem_ctx,
+                                            pszDomainName,
+                                            pszHostName,
+                                            sslist,
+                                            num_addrs);
+               if (probe == NULL) {
+                       TALLOC_FREE(mem_ctx);
+                       return ERROR_DNS_NO_MEMORY;
+               }
 
-               if (!ERR_DNS_IS_OK(err)) {
-                       DEBUG(3,("DoDNSUpdate: failed to probe DNS\n"));
-                       goto error;
+               ret = dns_cli_request(mem_ctx,
+                                     pszServerAddress,
+                                     probe,
+                                     &reply);
+               if (ret != 0) {
+                       TALLOC_FREE(mem_ctx);
+                       return ERROR_DNS_SOCKET_ERROR;
                }
 
-               if ((dns_response_code(resp->flags) == DNS_NO_ERROR) &&
-                   (flags & DNS_UPDATE_PROBE_SUFFICIENT)) {
+               if ((flags & DNS_UPDATE_PROBE_SUFFICIENT) &&
+                   ((reply->operation & DNS_RCODE) == DNS_RCODE_OK))
+               {
                        TALLOC_FREE(mem_ctx);
                        return ERROR_DNS_SUCCESS;
                }
@@ -158,27 +172,32 @@ DNS_ERROR DoDNSUpdate(const char *pszServerAddress,
 
        if (flags & DNS_UPDATE_UNSIGNED) {
 
-               /*
-                * First try without signing
-                */
+               struct dns_name_packet *update = NULL, *reply = NULL;
+               int ret;
 
-               err = dns_create_update_request(mem_ctx,
-                                               pszDomainName,
-                                               pszHostName,
-                                               sslist,
-                                               num_addrs,
-                                               ttl,
-                                               &req);
-               if (!ERR_DNS_IS_OK(err)) goto error;
+               update = dns_cli_create_update(mem_ctx,
+                                              pszDomainName,
+                                              pszHostName,
+                                              sslist,
+                                              num_addrs,
+                                              ttl);
+               if (update == NULL) {
+                       TALLOC_FREE(mem_ctx);
+                       return ERROR_DNS_NO_MEMORY;
+               }
 
-               err = dns_update_transaction(mem_ctx, conn, req, &resp);
-               if (!ERR_DNS_IS_OK(err)) {
-                       DEBUG(3,("DoDNSUpdate: unsigned update failed\n"));
-                       goto error;
+               ret = dns_cli_request(mem_ctx,
+                                     pszServerAddress,
+                                     update,
+                                     &reply);
+               if (ret != 0) {
+                       TALLOC_FREE(mem_ctx);
+                       return ERROR_DNS_SOCKET_ERROR;
                }
 
-               if ((dns_response_code(resp->flags) == DNS_NO_ERROR) &&
-                   (flags & DNS_UPDATE_UNSIGNED_SUFFICIENT)) {
+               if ((flags & DNS_UPDATE_UNSIGNED_SUFFICIENT) &&
+                   ((reply->operation & DNS_RCODE) == DNS_RCODE_OK))
+               {
                        TALLOC_FREE(mem_ctx);
                        return ERROR_DNS_SUCCESS;
                }
@@ -190,15 +209,19 @@ DNS_ERROR DoDNSUpdate(const char *pszServerAddress,
        if (flags & DNS_UPDATE_SIGNED) {
                struct gensec_security *gensec = NULL;
                char *keyname = NULL;
-
-               err = dns_create_update_request(mem_ctx,
-                                               pszDomainName,
-                                               pszHostName,
-                                               sslist,
-                                               num_addrs,
-                                               ttl,
-                                               &req);
-               if (!ERR_DNS_IS_OK(err)) goto error;
+               struct dns_name_packet *update = NULL, *reply = NULL;
+               int ret;
+
+               update = dns_cli_create_update(mem_ctx,
+                                              pszDomainName,
+                                              pszHostName,
+                                              sslist,
+                                              num_addrs,
+                                              ttl);
+               if (update == NULL) {
+                       TALLOC_FREE(mem_ctx);
+                       return ERROR_DNS_NO_MEMORY;
+               }
 
                if (!(keyname = dns_generate_keyname( mem_ctx ))) {
                        err = ERROR_DNS_NO_MEMORY;
@@ -229,16 +252,28 @@ DNS_ERROR DoDNSUpdate(const char *pszServerAddress,
                if (!ERR_DNS_IS_OK(err))
                        goto error;
 
-               err = dns_sign_update(req, gensec, keyname,
-                                     "gss.microsoft.com", time(NULL), 3600);
-
-               if (!ERR_DNS_IS_OK(err)) goto error;
+               ret = dns_cli_sign_packet(update,
+                                         gensec,
+                                         gensec_sign_packet,
+                                         keyname,
+                                         "gss.microsoft.com");
+               if (ret != 0) {
+                       err = ERROR_DNS_GSS_ERROR;
+                       goto error;
+               }
 
-               err = dns_update_transaction(mem_ctx, conn, req, &resp);
-               if (!ERR_DNS_IS_OK(err)) goto error;
+               ret = dns_cli_request(mem_ctx,
+                                     pszServerAddress,
+                                     update,
+                                     &reply);
+               if (ret != 0) {
+                       TALLOC_FREE(mem_ctx);
+                       return ERROR_DNS_SOCKET_ERROR;
+               }
 
-               err = (dns_response_code(resp->flags) == DNS_NO_ERROR) ?
-                       ERROR_DNS_SUCCESS : ERROR_DNS_UPDATE_FAILED;
+               err = ((reply->operation & DNS_RCODE) == DNS_RCODE_OK)
+                             ? ERROR_DNS_SUCCESS
+                             : ERROR_DNS_UPDATE_FAILED;
 
                if (!ERR_DNS_IS_OK(err)) {
                        DEBUG(3,("DoDNSUpdate: signed update failed\n"));