diff --git a/CHANGES b/CHANGES index 8aa287d905..b22f5d1b96 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +3000. [bug] More TKEY/GSS fixes: + - nsupdate can now get the default realm from + the user's Kerberos principal + - corrected gsstest compilation flags + - improved documentation + - fixed some NULL dereferences + [RT #22795] + 2999. [func] Add GOST support (RFC 5933). [RT #20639] 2998. [func] Add isc_task_beginexclusive and isc_task_endexclusive diff --git a/bin/named/query.c b/bin/named/query.c index 738d08566b..558ec3908a 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.349 2010/12/16 09:51:27 jinmei Exp $ */ +/* $Id: query.c,v 1.350 2010/12/24 02:20:47 each Exp $ */ /*! \file */ @@ -4342,7 +4342,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) } is_staticstub_zone = ISC_FALSE; - if (is_zone) { + if (is_zone && zone != NULL) { authoritative = ISC_TRUE; if (dns_zone_gettype(zone) == dns_zone_staticstub) is_staticstub_zone = ISC_TRUE; diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 01fea441a1..02722853e5 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: nsupdate.c,v 1.187 2010/12/18 01:56:19 each Exp $ */ +/* $Id: nsupdate.c,v 1.188 2010/12/24 02:20:47 each Exp $ */ /*! \file */ @@ -2431,6 +2431,58 @@ sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, } #ifdef GSSAPI + +/* + * Get the realm from the users kerberos ticket if possible + */ +static void +get_ticket_realm(isc_mem_t *mctx) +{ + krb5_context ctx; + krb5_error_code rc; + krb5_ccache ccache; + krb5_principal princ; + char *name, *ticket_realm; + + rc = krb5_init_context(&ctx); + if (rc != 0) + return; + + rc = krb5_cc_default(ctx, &ccache); + if (rc != 0) { + krb5_free_context(ctx); + return; + } + + rc = krb5_cc_get_principal(ctx, ccache, &princ); + if (rc != 0) { + krb5_cc_close(ctx, ccache); + krb5_free_context(ctx); + return; + } + + rc = krb5_unparse_name(ctx, princ, &name); + if (rc != 0) { + krb5_free_principal(ctx, princ); + krb5_cc_close(ctx, ccache); + krb5_free_context(ctx); + return; + } + + ticket_realm = strrchr(name, '@'); + if (ticket_realm != NULL) { + realm = isc_mem_strdup(mctx, ticket_realm); + } + + free(name); + krb5_free_principal(ctx, princ); + krb5_cc_close(ctx, ccache); + krb5_free_context(ctx); + if (realm != NULL && debugging) + fprintf(stderr, "Found realm from ticket: %s\n", realm+1); +} + + static void start_gssrequest(dns_name_t *master, dns_name_t *zone) { @@ -2472,6 +2524,9 @@ start_gssrequest(dns_name_t *master, dns_name_t *zone) dns_fixedname_init(&fname); servname = dns_fixedname_name(&fname); + if (realm == NULL) + get_ticket_realm(mctx); + result = isc_string_printf(servicename, sizeof(servicename), "DNS/%s%s", namestr, realm ? realm : ""); if (result != ISC_R_SUCCESS) diff --git a/bin/tests/dst/Makefile.in b/bin/tests/dst/Makefile.in index 7eb069ec41..f442a8031c 100644 --- a/bin/tests/dst/Makefile.in +++ b/bin/tests/dst/Makefile.in @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.50 2009/12/05 23:31:40 each Exp $ +# $Id: Makefile.in,v 1.51 2010/12/24 02:20:47 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -24,7 +24,7 @@ top_srcdir = @top_srcdir@ CINCLUDES = ${TEST_INCLUDES} ${DNS_INCLUDES} \ ${ISC_INCLUDES} @DST_GSSAPI_INC@ -CDEFINES = +CDEFINES = @USE_GSSAPI@ CWARNINGS = DNSLIBS = ../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ diff --git a/bin/tests/dst/gsstest.c b/bin/tests/dst/gsstest.c index 3344c8806f..9b43905fa4 100755 --- a/bin/tests/dst/gsstest.c +++ b/bin/tests/dst/gsstest.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gsstest.c,v 1.10 2010/12/20 23:47:20 tbox Exp $ */ +/* $Id: gsstest.c,v 1.11 2010/12/24 02:20:47 each Exp $ */ #include @@ -359,7 +359,7 @@ initctx1(isc_task_t *task, isc_event_t *event) { printf("Initctx - context name we're using: %s\n", contextname); printf("Negotiating GSSAPI context: "); - printf(gssid); + printf("%s", gssid); printf("\n"); /* @@ -388,7 +388,8 @@ initctx1(isc_task_t *task, isc_event_t *event) { gssctx = GSS_C_NO_CONTEXT; result = dns_tkey_buildgssquery(query, dns_fixedname_name(&servername), dns_fixedname_name(&gssname), - NULL, 36000, &gssctx, ISC_TRUE); + NULL, 36000, &gssctx, ISC_TRUE, + NULL, mctx, NULL); CHECK("dns_tkey_buildgssquery", result); printf("Sending context token to server\n"); diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 7ab741949e..3e3603726a 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + BIND 9 Administrator Reference Manual @@ -1792,13 +1792,14 @@ controls { - The tkey-gssapi-credential, - tkey-gssapi-keytab - and tkey-domain clauses in the - options statement enable the - server to negotiate keys that can be matched against those - in update-policy or - allow-update. + Dynamic updates using Kerberos signed requests can be made + using the TKEY/GSS protocol by setting either the + tkey-gssapi-keytab option, or alternatively + by setting both the tkey-gssapi-credential + and tkey-domain options. Once enabled, + Kerberos signed requests will be matched against the update + policies for the zone, using the Kerberos principal as the + signer for the request. diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c index 90e8cccba5..e7717576f6 100644 --- a/lib/dns/gssapictx.c +++ b/lib/dns/gssapictx.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gssapictx.c,v 1.22 2010/12/22 02:33:12 marka Exp $ */ +/* $Id: gssapictx.c,v 1.23 2010/12/24 02:20:47 each Exp $ */ #include @@ -516,82 +516,6 @@ dst_gssapi_releasecred(gss_cred_id_t *cred) { } #ifdef GSSAPI -/* - * GSSAPI with krb5 doesn't have a way to set the default realm, as it - * doesn't offer any access to the krb5 context that it uses. The only - * way to do an nsupdate call on a realm that isn't the default realm in - * /etc/krb5.conf is to create a temporary krb5.conf and put the right - * realm in there as the default realm, then set KRB5_CONFIG to point - * at that temporary krb5.conf. This is a disgusting hack, but it is - * the best we can do with GSSAPI. - * - * To try to reduce the impact, this routine checks if the default - * realm is already correct. If it is, then we don't need to do - * anything. If not, then we create the temporary krb5.conf. - */ -static void -check_zone(dns_name_t *zone, isc_mem_t *mctx, char **tmpfile) { - krb5_context ctx; - int kret; - char *realm; - char buf[1024]; - isc_result_t ret; - FILE *fp = NULL; - char *p, *template; - - if (getenv("KRB5_CONFIG") != NULL) { - /* the user has specifically set a KRB5_CONFIG to - use. Don't override it, as they may know what they are - doing */ - return; - } - - dns_name_format(zone, buf, sizeof(buf)); - - /* gssapi wants the realm in upper case */ - for (p=buf; *p; p++) { - if (islower((int)*p)) - *p = toupper((int)*p); - } - - kret = krb5_init_context(&ctx); - if (kret != 0) - return; - - kret = krb5_get_default_realm(ctx, &realm); - if (kret == 0 && strcmp(buf, realm) == 0) { - /* the krb5.conf is correct. */ - krb5_free_context(ctx); - return; - } - - gss_log(3, "zone '%s' doesn't match KRB5 default realm '%s'", - buf, realm); - - template = isc_mem_strdup(mctx, "/tmp/krb5.conf.XXXXXX"); - if (template == NULL) { - krb5_free_context(ctx); - return; - } - - ret = isc_file_openunique(template, &fp); - if (ret != ISC_R_SUCCESS) { - krb5_free_context(ctx); - return; - } - - fprintf(fp, "[libdefaults]\n"); - fprintf(fp, "\tdefault_realm = %s\n", buf); - fprintf(fp, "\tdns_lookup_kdc = true\n"); - fclose(fp); - - setenv("KRB5_CONFIG", template, 1); - - *tmpfile = template; - - krb5_free_context(ctx); -} - /* * Format a gssapi error message info into a char ** on the given memory * context. This is used to return gssapi error messages back up the @@ -635,10 +559,6 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken, REQUIRE(gssctx != NULL); REQUIRE(mctx != NULL); - if (zone != NULL && mctx != NULL) { - check_zone(zone, mctx, &tmpfile); - } - isc_buffer_init(&namebuf, array, sizeof(array)); name_to_gbuffer(name, &namebuf, &gnamebuf); diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c index 117e0b8e72..c9e0fe7094 100644 --- a/lib/dns/tsig.c +++ b/lib/dns/tsig.c @@ -16,7 +16,7 @@ */ /* - * $Id: tsig.c,v 1.143 2010/12/09 00:54:34 marka Exp $ + * $Id: tsig.c,v 1.144 2010/12/24 02:20:47 each Exp $ */ /*! \file */ #include @@ -203,8 +203,10 @@ tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) { else strcpy(namestr, ""); - if (key != NULL && key->generated) + if (key != NULL && key->generated && key->creator) dns_name_format(key->creator, creatorstr, sizeof(creatorstr)); + else + strcpy(creatorstr, ""); va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap);