From: Volker Lendecke Date: Thu, 14 May 2026 08:14:58 +0000 (+0200) Subject: lib/addns: Use NDR marshalling for signed DNS updates X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b3d20ab58bc53b8e0a4bb607b173e806a9637a1f;p=thirdparty%2Fsamba.git lib/addns: Use NDR marshalling for signed DNS updates 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 Reviewed-by: Stefan Metzmacher --- diff --git a/lib/addns/dns.h b/lib/addns/dns.h index 91e4568eb57..72fc08eb542 100644 --- a/lib/addns/dns.h +++ b/lib/addns/dns.h @@ -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 */ diff --git a/lib/addns/dnsgss.c b/lib/addns/dnsgss.c index 71411430ce9..c121e30e236 100644 --- a/lib/addns/dnsgss.c +++ b/lib/addns/dnsgss.c @@ -30,17 +30,18 @@ #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; -} diff --git a/lib/addns/dnsmarshall.c b/lib/addns/dnsmarshall.c index c95420304f0..f68d875cc0a 100644 --- a/lib/addns/dnsmarshall.c +++ b/lib/addns/dnsmarshall.c @@ -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; diff --git a/lib/addns/dnsrecord.c b/lib/addns/dnsrecord.c index 47d1ed0458f..d8a29453f17 100644 --- a/lib/addns/dnsrecord.c +++ b/lib/addns/dnsrecord.c @@ -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; inum_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; inum_updates, &req->updates); - if (!ERR_DNS_IS_OK(err)) - goto error; - } - - *preq = req; - return ERROR_DNS_SUCCESS; - - error: - TALLOC_FREE(req); - return err; -} diff --git a/source3/utils/net_ads_join_dns.c b/source3/utils/net_ads_join_dns.c index a6ea8b4b33e..86ec5a7a529 100644 --- a/source3/utils/net_ads_join_dns.c +++ b/source3/utils/net_ads_join_dns.c @@ -195,7 +195,7 @@ do_update: dnsdomain, machine_name, creds, - addrs, + addrs, num_addrs, flags, ttl, diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c index e6086d8fac6..1a8d3e8877f 100644 --- a/source3/utils/net_dns.c +++ b/source3/utils/net_dns.c @@ -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"));