diff --git a/CHANGES b/CHANGES index 52b4cf5e4e..5d20dbea66 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +6184. [func] Special-case code that was added to allow GSS-TSIG + to work around bugs in the Windows 2000 version of + Active Directory has been removed. The 'nsupdate -o' + option and 'oldgsstsig' command have been + deprecated, and are now treated as synonyms for + 'nsupdate -g' and 'gsstsig' respectively. [GL #4012] + 6183. [bug] Fix a serve-stale bug where a delegation from cache could be returned to the client. [GL #3950] diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index a199892254..87affae84e 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -119,8 +119,6 @@ static bool is_dst_up = false; static bool use_tls = false; static bool usevc = false; static bool usegsstsig = false; -static bool use_win2k_gsstsig = false; -static bool tried_other_gsstsig = false; static bool local_only = false; static isc_nm_t *netmgr = NULL; static isc_loopmgr_t *loopmgr = NULL; @@ -376,7 +374,6 @@ reset_system(void) { if (gssring != NULL) { dns_tsigkeyring_detach(&gssring); } - tried_other_gsstsig = false; } } @@ -1196,11 +1193,9 @@ parse_args(int argc, char **argv) { break; case 'g': usegsstsig = true; - use_win2k_gsstsig = false; break; case 'o': usegsstsig = true; - use_win2k_gsstsig = true; break; case 'O': use_tls = true; @@ -2303,7 +2298,6 @@ do_next_command(char *cmdline) { if (strcasecmp(word, "gsstsig") == 0) { #if HAVE_GSSAPI usegsstsig = true; - use_win2k_gsstsig = false; #else /* HAVE_GSSAPI */ fprintf(stderr, "gsstsig not supported\n"); #endif /* HAVE_GSSAPI */ @@ -2312,7 +2306,6 @@ do_next_command(char *cmdline) { if (strcasecmp(word, "oldgsstsig") == 0) { #if HAVE_GSSAPI usegsstsig = true; - use_win2k_gsstsig = true; #else /* HAVE_GSSAPI */ fprintf(stderr, "gsstsig not supported\n"); #endif /* HAVE_GSSAPI */ @@ -2338,8 +2331,6 @@ do_next_command(char *cmdline) { "the request)\n" "gsstsig (use GSS_TSIG to " "sign the request)\n" - "oldgsstsig (use Microsoft's " - "GSS_TSIG to sign the request)\n" "zone name (set the zone to be " "updated)\n" "class CLASS (set the zone's DNS " @@ -3108,8 +3099,7 @@ start_gssrequest(dns_name_t *primary) { /* Build first request. */ context = GSS_C_NO_CONTEXT; result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0, - &context, use_win2k_gsstsig, gmctx, - &err_message); + &context, gmctx, &err_message); if (result == ISC_R_FAILURE) { fprintf(stderr, "tkey query failed: %s\n", err_message != NULL ? err_message : "unknown error"); @@ -3234,19 +3224,6 @@ recvgss(void *arg) { fatal("invalid OPCODE in response to GSS-TSIG query"); } - if (rcvmsg->rcode == dns_rcode_formerr && !tried_other_gsstsig) { - ddebug("recvgss trying %s GSS-TSIG", - use_win2k_gsstsig ? "Standard" : "Win2k"); - if (use_win2k_gsstsig) { - use_win2k_gsstsig = false; - } else { - use_win2k_gsstsig = true; - } - tried_other_gsstsig = true; - start_gssrequest(&restart_primary); - goto done; - } - if (rcvmsg->rcode != dns_rcode_noerror && rcvmsg->rcode != dns_rcode_nxdomain) { @@ -3261,8 +3238,7 @@ recvgss(void *arg) { tsigkey = NULL; result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname, &context, - &tsigkey, gssring, use_win2k_gsstsig, - &err_message); + &tsigkey, gssring, &err_message); switch (result) { case DNS_R_CONTINUE: dns_message_detach(&rcvmsg); @@ -3310,7 +3286,6 @@ recvgss(void *arg) { err_message != NULL ? err_message : ""); } -done: dns_request_destroy(&request); dns_message_detach(&tsigquery); diff --git a/bin/nsupdate/nsupdate.rst b/bin/nsupdate/nsupdate.rst index 481fbbb6ef..88263904ed 100644 --- a/bin/nsupdate/nsupdate.rst +++ b/bin/nsupdate/nsupdate.rst @@ -149,8 +149,10 @@ Options .. option:: -o - This option enables a non-standards-compliant variant of GSS-TSIG - used by Windows 2000. + This option is deprecated. Previously, it enabled a + non-standards-compliant variant of GSS-TSIG that was used by Windows + 2000. Since that OS is now long past its end of life, this option is + now treated as a synonym for :option:`-g`. .. option:: -O @@ -300,8 +302,9 @@ The command formats and their meanings are as follows: :option:`-g` on the command line. ``oldgsstsig`` - This command uses the Windows 2000 version of GSS-TSIG to sign the updates. This is - equivalent to specifying :option:`-o` on the command line. + This command is deprecated and will be removed in a future release. + Previously, it caused ``nsupdate`` to use the Windows 2000 version of + GSS-TSIG to sign updates. It is now treated as a synonym for ``gsstsig``. ``realm [realm_name]`` When using GSS-TSIG, this command specifies the use of ``realm_name`` rather than the default realm diff --git a/doc/notes/notes-current.rst b/doc/notes/notes-current.rst index b5ba7b17e7..1e3c2e00e9 100644 --- a/doc/notes/notes-current.rst +++ b/doc/notes/notes-current.rst @@ -37,7 +37,12 @@ New Features Removed Features ~~~~~~~~~~~~~~~~ -- None. +- Special-case code that was originally added to allow GSS-TSIG to work + around bugs in the Windows 2000 version of Active Directory has now + been removed since Windows 2000 is long past end-of-life. + The ``nsupdate -o`` option and the ``oldgsstsig`` command to ``nsupdate`` + have been deprecated, and are now treated as synonyms for ``nsupdate -g`` + and ``gsstsig`` respectively. :gl:`#4012` Feature Changes ~~~~~~~~~~~~~~~ diff --git a/lib/dns/include/dns/tkey.h b/lib/dns/include/dns/tkey.h index 059a97f1ff..ac65603b03 100644 --- a/lib/dns/include/dns/tkey.h +++ b/lib/dns/include/dns/tkey.h @@ -90,7 +90,7 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, isc_result_t dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name, const dns_name_t *gname, isc_buffer_t *intoken, - uint32_t lifetime, dns_gss_ctx_id_t *context, bool win2k, + uint32_t lifetime, dns_gss_ctx_id_t *context, isc_mem_t *mctx, char **err_message); /*%< * Builds a query containing a TKEY that will generate a GSSAPI context. @@ -102,8 +102,6 @@ dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name, *\li 'gname' is a valid name *\li 'context' is a pointer to a valid gss_ctx_id_t * (which may have the value GSS_C_NO_CONTEXT) - *\li 'win2k' when true says to turn on some hacks to work - * with the non-standard GSS-TSIG of Windows 2000 * * Returns: *\li ISC_R_SUCCESS msg was successfully updated to include the @@ -116,9 +114,8 @@ isc_result_t dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, const dns_name_t *server, dns_gss_ctx_id_t *context, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring, - bool win2k, char **err_message); - -/* + char **err_message); +/*%< * Client side negotiation of GSS-TSIG. Process the response * to a TKEY, and establish a TSIG key if negotiation was successful. * Build a response to the input TKEY message. Can take multiple @@ -134,8 +131,6 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, * if non-NULL must point to NULL * 'ring' is the keyring in which to establish the key, * or NULL - * 'win2k' when true says to turn on some hacks to work - * with the non-standard GSS-TSIG of Windows 2000 * * Returns: * ISC_R_SUCCESS context was successfully established @@ -144,5 +139,4 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, * DNS_R_CONTINUE additional context negotiation is required; * send the new qmsg to the server */ - ISC_LANG_ENDDECLS diff --git a/lib/dns/include/dns/tsig.h b/lib/dns/include/dns/tsig.h index c5452f67fb..e8b10b3053 100644 --- a/lib/dns/include/dns/tsig.h +++ b/lib/dns/include/dns/tsig.h @@ -35,8 +35,6 @@ extern const dns_name_t *dns_tsig_hmacmd5_name; #define DNS_TSIG_HMACMD5_NAME dns_tsig_hmacmd5_name extern const dns_name_t *dns_tsig_gssapi_name; #define DNS_TSIG_GSSAPI_NAME dns_tsig_gssapi_name -extern const dns_name_t *dns_tsig_gssapims_name; -#define DNS_TSIG_GSSAPIMS_NAME dns_tsig_gssapims_name extern const dns_name_t *dns_tsig_hmacsha1_name; #define DNS_TSIG_HMACSHA1_NAME dns_tsig_hmacsha1_name extern const dns_name_t *dns_tsig_hmacsha224_name; diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c index c7262c1688..37e283c50e 100644 --- a/lib/dns/tkey.c +++ b/lib/dns/tkey.c @@ -197,12 +197,9 @@ process_gsstkey(dns_message_t *msg, dns_name_t *name, dns_rdata_tkey_t *tkeyin, return (ISC_R_NOPERM); } - if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME) && - !dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPIMS_NAME)) - { + if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME)) { tkeyout->error = dns_tsigerror_badalg; - tkey_log("process_gsstkey(): dns_tsigerror_badalg"); /* XXXSRA - */ + tkey_log("process_gsstkey(): dns_tsigerror_badalg"); return (ISC_R_SUCCESS); } @@ -403,20 +400,10 @@ dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx, result = dns_message_findname(msg, DNS_SECTION_ADDITIONAL, qname, dns_rdatatype_tkey, 0, &name, &tkeyset); if (result != ISC_R_SUCCESS) { - /* - * Try the answer section, since that's where Win2000 - * puts it. - */ - name = NULL; - if (dns_message_findname(msg, DNS_SECTION_ANSWER, qname, - dns_rdatatype_tkey, 0, &name, - &tkeyset) != ISC_R_SUCCESS) - { - result = DNS_R_FORMERR; - tkey_log("dns_tkey_processquery: couldn't find a TKEY " - "matching the question"); - goto failure; - } + result = DNS_R_FORMERR; + tkey_log("dns_tkey_processquery: couldn't find a TKEY " + "matching the question"); + goto failure; } result = dns_rdataset_first(tkeyset); if (result != ISC_R_SUCCESS) { @@ -614,8 +601,7 @@ failure: } static isc_result_t -buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey, - bool win2k) { +buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey) { dns_name_t *qname = NULL, *aname = NULL; dns_rdataset_t *question = NULL, *tkeyset = NULL; dns_rdatalist_t *tkeylist = NULL; @@ -662,16 +648,7 @@ buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey, ISC_LIST_APPEND(aname->list, tkeyset, link); dns_message_addname(msg, qname, DNS_SECTION_QUESTION); - - /* - * Windows 2000 needs this in the answer section, not the additional - * section where the RFC specifies. - */ - if (win2k) { - dns_message_addname(msg, aname, DNS_SECTION_ANSWER); - } else { - dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL); - } + dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL); return (ISC_R_SUCCESS); } @@ -679,7 +656,7 @@ buildquery(dns_message_t *msg, const dns_name_t *name, dns_rdata_tkey_t *tkey, isc_result_t dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name, const dns_name_t *gname, isc_buffer_t *intoken, - uint32_t lifetime, dns_gss_ctx_id_t *context, bool win2k, + uint32_t lifetime, dns_gss_ctx_id_t *context, isc_mem_t *mctx, char **err_message) { dns_rdata_tkey_t tkey; isc_result_t result; @@ -707,13 +684,7 @@ dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name, ISC_LINK_INIT(&tkey.common, link); tkey.mctx = NULL; dns_name_init(&tkey.algorithm, NULL); - - if (win2k) { - dns_name_clone(DNS_TSIG_GSSAPIMS_NAME, &tkey.algorithm); - } else { - dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm); - } - + dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm); tkey.inception = now; tkey.expire = now + lifetime; tkey.mode = DNS_TKEYMODE_GSSAPI; @@ -723,7 +694,7 @@ dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name, tkey.other = NULL; tkey.otherlen = 0; - return (buildquery(msg, name, &tkey, win2k)); + return (buildquery(msg, name, &tkey)); } static isc_result_t @@ -759,7 +730,7 @@ isc_result_t dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, const dns_name_t *server, dns_gss_ctx_id_t *context, dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring, - bool win2k, char **err_message) { + char **err_message) { dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT; dns_name_t *tkeyname; dns_rdata_tkey_t rtkey, qtkey, tkey; @@ -784,14 +755,7 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL)); freertkey = true; - if (win2k) { - RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata, - DNS_SECTION_ANSWER)); - } else { - RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata, - DNS_SECTION_ADDITIONAL)); - } - + RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata, DNS_SECTION_ADDITIONAL)); RETERR(dns_rdata_tostruct(&qtkeyrdata, &qtkey, NULL)); if (rtkey.error != dns_rcode_noerror || @@ -825,12 +789,7 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, ISC_LINK_INIT(&tkey.common, link); tkey.mctx = NULL; dns_name_init(&tkey.algorithm, NULL); - - if (win2k) { - dns_name_clone(DNS_TSIG_GSSAPIMS_NAME, &tkey.algorithm); - } else { - dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm); - } + dns_name_clone(DNS_TSIG_GSSAPI_NAME, &tkey.algorithm); tkey.inception = qtkey.inception; tkey.expire = qtkey.expire; @@ -842,7 +801,7 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, tkey.otherlen = 0; dns_message_reset(qmsg, DNS_MESSAGE_INTENTRENDER); - RETERR(buildquery(qmsg, tkeyname, &tkey, win2k)); + RETERR(buildquery(qmsg, tkeyname, &tkey)); return (DNS_R_CONTINUE); } @@ -856,10 +815,8 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg, */ RETERR(dns_tsigkey_createfromkey( - tkeyname, - (win2k ? DNS_TSIG_GSSAPIMS_NAME : DNS_TSIG_GSSAPI_NAME), dstkey, - true, false, NULL, rtkey.inception, rtkey.expire, ring->mctx, - ring, outkey)); + tkeyname, DNS_TSIG_GSSAPI_NAME, dstkey, true, false, NULL, + rtkey.inception, rtkey.expire, ring->mctx, ring, outkey)); dst_key_free(&dstkey); dns_rdata_freestruct(&rtkey); return (result); diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c index 5de0ed7615..15358fe834 100644 --- a/lib/dns/tsig.c +++ b/lib/dns/tsig.c @@ -63,16 +63,6 @@ static dns_name_t const gsstsig = DNS_NAME_INITABSOLUTE(gsstsig_ndata, gsstsig_offsets); const dns_name_t *dns_tsig_gssapi_name = &gsstsig; -/* - * Since Microsoft doesn't follow its own standard, we will use this - * alternate name as a second guess. - */ -static unsigned char gsstsigms_ndata[] = "\003gss\011microsoft\003com"; -static unsigned char gsstsigms_offsets[] = { 0, 4, 14, 18 }; -static dns_name_t const gsstsigms = DNS_NAME_INITABSOLUTE(gsstsigms_ndata, - gsstsigms_offsets); -const dns_name_t *dns_tsig_gssapims_name = &gsstsigms; - static unsigned char hmacsha1_ndata[] = "\011hmac-sha1"; static unsigned char hmacsha1_offsets[] = { 0, 10 }; static dns_name_t const hmacsha1 = DNS_NAME_INITABSOLUTE(hmacsha1_ndata, @@ -108,7 +98,6 @@ static const struct { unsigned int dstalg; } known_algs[] = { { &hmacmd5, DST_ALG_HMACMD5 }, { &gsstsig, DST_ALG_GSSAPI }, - { &gsstsigms, DST_ALG_GSSAPI }, { &hmacsha1, DST_ALG_HMACSHA1 }, { &hmacsha224, DST_ALG_HMACSHA224 }, { &hmacsha256, DST_ALG_HMACSHA256 }, diff --git a/tests/dns/tsig_test.c b/tests/dns/tsig_test.c index a7d11e9e81..6380e3e09b 100644 --- a/tests/dns/tsig_test.c +++ b/tests/dns/tsig_test.c @@ -503,8 +503,6 @@ ISC_RUN_TEST_IMPL(algfromname) { assert_int_equal(dns__tsig_algfromname(DNS_TSIG_GSSAPI_NAME), DST_ALG_GSSAPI); - assert_int_equal(dns__tsig_algfromname(DNS_TSIG_GSSAPIMS_NAME), - DST_ALG_GSSAPI); assert_int_equal(dns__tsig_algfromname(dns_rootname), 0); } @@ -538,7 +536,6 @@ ISC_RUN_TEST_IMPL(algnamefromname) { test_name("hmac-sha512", DNS_TSIG_HMACSHA512_NAME); test_name("gss-tsig", DNS_TSIG_GSSAPI_NAME); - test_name("gss.microsoft.com", DNS_TSIG_GSSAPIMS_NAME); /* try another name that isn't a standard algorithm name */ assert_null(dns__tsig_algnamefromname(dns_rootname));