d56ed2
From c8cd2cd7f21ce56f93532a6d5f26239e60657acb Mon Sep 17 00:00:00 2001
d56ed2
From: Tomas Hozza <thozza@redhat.com>
d56ed2
Date: Thu, 25 Jun 2015 14:53:31 +0200
d56ed2
Subject: [PATCH] nsupdate: Don't extract REAML from ticket, but leave it up to
d56ed2
 GSSAPI
d56ed2
d56ed2
The current implementation of nsupdate does not work correctly with
d56ed2
GSSAPI in cross realm trust scenarios. The realm is currently
d56ed2
extracted from local kerberos ticket instead of letting GSSAPI to
d56ed2
figure out the realm based on the remote nameserver hostname.
d56ed2
d56ed2
RFC 4752 section 3.1 states that the client should use
d56ed2
GSS_C_NT_HOSTBASED_SERVICE when calling gss_import_name().
d56ed2
d56ed2
nsupdate now leaves the realm detection up to GSSAPI, if the realm is
d56ed2
not specified explicitly using the 'realm' option. If the option is
d56ed2
used, the old behavior is preserved.
d56ed2
d56ed2
Signed-off-by: Tomas Hozza <thozza@redhat.com>
d56ed2
---
d56ed2
 bin/nsupdate/nsupdate.1       |  3 +-
d56ed2
 bin/nsupdate/nsupdate.c       | 72 ++++++++-----------------------------------
d56ed2
 bin/nsupdate/nsupdate.docbook |  2 +-
d56ed2
 bin/nsupdate/nsupdate.html    |  2 +-
d56ed2
 bin/tests/dst/gsstest.c       |  4 +--
d56ed2
 lib/dns/gssapictx.c           | 16 +++++++---
d56ed2
 lib/dns/include/dns/tkey.h    | 24 +++++++++------
d56ed2
 lib/dns/include/dst/gssapi.h  |  8 +++--
d56ed2
 lib/dns/tkey.c                | 28 +++++++++--------
d56ed2
 9 files changed, 65 insertions(+), 94 deletions(-)
d56ed2
d56ed2
diff --git a/bin/nsupdate/nsupdate.1 b/bin/nsupdate/nsupdate.1
d56ed2
index 1e2dcaf..c847fb8 100644
d56ed2
--- a/bin/nsupdate/nsupdate.1
d56ed2
+++ b/bin/nsupdate/nsupdate.1
d56ed2
@@ -259,8 +259,7 @@ on the commandline.
d56ed2
 .RS 4
d56ed2
 When using GSS\-TSIG use
d56ed2
 \fIrealm_name\fR
d56ed2
-rather than the default realm in
d56ed2
-\fIkrb5.conf\fR. If no realm is specified the saved realm is cleared.
d56ed2
+rather than leaving the realm detection up to GSSAPI. If no realm is specified the saved realm is cleared.
d56ed2
 .RE
d56ed2
 .PP
d56ed2
 \fB[prereq]\fR\fB nxdomain\fR {domain\-name}
d56ed2
diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c
d56ed2
index b901e03..644e3d9 100644
d56ed2
--- a/bin/nsupdate/nsupdate.c
d56ed2
+++ b/bin/nsupdate/nsupdate.c
d56ed2
@@ -2489,57 +2489,6 @@ sendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr,
d56ed2
 
d56ed2
 #ifdef GSSAPI
d56ed2
 
d56ed2
-/*
d56ed2
- * Get the realm from the users kerberos ticket if possible
d56ed2
- */
d56ed2
-static void
d56ed2
-get_ticket_realm(isc_mem_t *mctx)
d56ed2
-{
d56ed2
-	krb5_context ctx;
d56ed2
-	krb5_error_code rc;
d56ed2
-	krb5_ccache ccache;
d56ed2
-	krb5_principal princ;
d56ed2
-	char *name, *ticket_realm;
d56ed2
-
d56ed2
-	rc = krb5_init_context(&ctx;;
d56ed2
-	if (rc != 0)
d56ed2
-		return;
d56ed2
-
d56ed2
-	rc = krb5_cc_default(ctx, &ccache);
d56ed2
-	if (rc != 0) {
d56ed2
-		krb5_free_context(ctx);
d56ed2
-		return;
d56ed2
-	}
d56ed2
-
d56ed2
-	rc = krb5_cc_get_principal(ctx, ccache, &princ);
d56ed2
-	if (rc != 0) {
d56ed2
-		krb5_cc_close(ctx, ccache);
d56ed2
-		krb5_free_context(ctx);
d56ed2
-		return;
d56ed2
-	}
d56ed2
-
d56ed2
-	rc = krb5_unparse_name(ctx, princ, &name);
d56ed2
-	if (rc != 0) {
d56ed2
-		krb5_free_principal(ctx, princ);
d56ed2
-		krb5_cc_close(ctx, ccache);
d56ed2
-		krb5_free_context(ctx);
d56ed2
-		return;
d56ed2
-	}
d56ed2
-
d56ed2
-	ticket_realm = strrchr(name, '@');
d56ed2
-	if (ticket_realm != NULL) {
d56ed2
-		realm = isc_mem_strdup(mctx, ticket_realm);
d56ed2
-	}
d56ed2
-
d56ed2
-	free(name);
d56ed2
-	krb5_free_principal(ctx, princ);
d56ed2
-	krb5_cc_close(ctx, ccache);
d56ed2
-	krb5_free_context(ctx);
d56ed2
-	if (realm != NULL && debugging)
d56ed2
-		fprintf(stderr, "Found realm from ticket: %s\n", realm+1);
d56ed2
-}
d56ed2
-
d56ed2
-
d56ed2
 static void
d56ed2
 start_gssrequest(dns_name_t *master) {
d56ed2
 	gss_ctx_id_t context;
d56ed2
@@ -2580,11 +2529,15 @@ start_gssrequest(dns_name_t *master) {
d56ed2
 	dns_fixedname_init(&fname);
d56ed2
 	servname = dns_fixedname_name(&fname);
d56ed2
 
d56ed2
-	if (realm == NULL)
d56ed2
-		get_ticket_realm(mctx);
d56ed2
-
d56ed2
-	result = isc_string_printf(servicename, sizeof(servicename),
d56ed2
-				   "DNS/%s%s", namestr, realm ? realm : "");
d56ed2
+	if (realm != NULL) {
d56ed2
+		/* Use explicit REALM passed as argument */
d56ed2
+		result = isc_string_printf(servicename, sizeof(servicename),
d56ed2
+				   "DNS/%s%s", namestr, realm);
d56ed2
+	} else {
d56ed2
+		/* Use service@host as advised in RFC4752 section 3.1 */
d56ed2
+		result = isc_string_printf(servicename, sizeof(servicename),
d56ed2
+				   "DNS@%s", namestr);
d56ed2
+	}
d56ed2
 	if (result != ISC_R_SUCCESS)
d56ed2
 		fatal("isc_string_printf(servicename) failed: %s",
d56ed2
 		      isc_result_totext(result));
d56ed2
@@ -2623,9 +2576,9 @@ start_gssrequest(dns_name_t *master) {
d56ed2
 
d56ed2
 	/* Build first request. */
d56ed2
 	context = GSS_C_NO_CONTEXT;
d56ed2
-	result = dns_tkey_buildgssquery(rmsg, keyname, servname, NULL, 0,
d56ed2
-					&context, use_win2k_gsstsig,
d56ed2
-					mctx, &err_message);
d56ed2
+	result = dns_tkey_buildgssquery(rmsg, keyname, servname,
d56ed2
+					realm != NULL ? ISC_TRUE : ISC_FALSE, NULL, 0,
d56ed2
+					&context, use_win2k_gsstsig, mctx, &err_message);
d56ed2
 	if (result == ISC_R_FAILURE)
d56ed2
 		fatal("tkey query failed: %s",
d56ed2
 		      err_message != NULL ? err_message : "unknown error");
d56ed2
@@ -2765,6 +2718,7 @@ recvgss(isc_task_t *task, isc_event_t *event) {
d56ed2
 
d56ed2
 	tsigkey = NULL;
d56ed2
 	result = dns_tkey_gssnegotiate(tsigquery, rcvmsg, servname,
d56ed2
+				       realm != NULL ? ISC_TRUE : ISC_FALSE,
d56ed2
 				       &context, &tsigkey, gssring,
d56ed2
 				       use_win2k_gsstsig,
d56ed2
 				       &err_message);
d56ed2
diff --git a/bin/nsupdate/nsupdate.docbook b/bin/nsupdate/nsupdate.docbook
d56ed2
index c54211c..bbcc681 100644
d56ed2
--- a/bin/nsupdate/nsupdate.docbook
d56ed2
+++ b/bin/nsupdate/nsupdate.docbook
d56ed2
@@ -418,7 +418,7 @@
d56ed2
           <listitem>
d56ed2
             <para>
d56ed2
 	      When using GSS-TSIG use <parameter>realm_name</parameter> rather
d56ed2
-	      than the default realm in <filename>krb5.conf</filename>.  If no
d56ed2
+	      than leaving the realm detection up to GSSAPI.  If no
d56ed2
 	      realm is specified the saved realm is cleared.
d56ed2
             </para>
d56ed2
           </listitem>
d56ed2
diff --git a/bin/nsupdate/nsupdate.html b/bin/nsupdate/nsupdate.html
d56ed2
index 276d4af..9c0eba0 100644
d56ed2
--- a/bin/nsupdate/nsupdate.html
d56ed2
+++ b/bin/nsupdate/nsupdate.html
d56ed2
@@ -327,7 +327,7 @@
d56ed2
           
d56ed2
 

d56ed2
 	      When using GSS-TSIG use realm_name rather
d56ed2
-	      than the default realm in krb5.conf.  If no
d56ed2
+	      than leaving the realm detection up to GSSAPI.  If no
d56ed2
 	      realm is specified the saved realm is cleared.
d56ed2
             

d56ed2
 
d56ed2
diff --git a/bin/tests/dst/gsstest.c b/bin/tests/dst/gsstest.c
d56ed2
index c1296f7..7c85d0b 100755
d56ed2
--- a/bin/tests/dst/gsstest.c
d56ed2
+++ b/bin/tests/dst/gsstest.c
d56ed2
@@ -309,7 +309,7 @@ initctx2(isc_task_t *task, isc_event_t *event) {
d56ed2
 	printf("Received token from server, calling gss_init_sec_context()\n");
d56ed2
 	isc_buffer_init(&outtoken, array, DNS_NAME_MAXTEXT + 1);
d56ed2
 	result = dns_tkey_processgssresponse(query, response,
d56ed2
-					     dns_fixedname_name(&gssname),
d56ed2
+					     dns_fixedname_name(&gssname), ISC_FALSE,
d56ed2
 					     &gssctx, &outtoken,
d56ed2
 					     &tsigkey, ring, NULL);
d56ed2
 	gssctx = *gssctxp;
d56ed2
@@ -396,7 +396,7 @@ initctx1(isc_task_t *task, isc_event_t *event) {
d56ed2
 	printf("Calling gss_init_sec_context()\n");
d56ed2
 	gssctx = GSS_C_NO_CONTEXT;
d56ed2
 	result = dns_tkey_buildgssquery(query, dns_fixedname_name(&servername),
d56ed2
-					dns_fixedname_name(&gssname),
d56ed2
+					dns_fixedname_name(&gssname), ISC_FALSE,
d56ed2
 					NULL, 36000, &gssctx, ISC_TRUE,
d56ed2
 					mctx, NULL);
d56ed2
 	CHECK("dns_tkey_buildgssquery", result);
d56ed2
diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c
d56ed2
index aeaeb85..21222e0 100644
d56ed2
--- a/lib/dns/gssapictx.c
d56ed2
+++ b/lib/dns/gssapictx.c
d56ed2
@@ -558,14 +558,15 @@ gss_err_message(isc_mem_t *mctx, isc_uint32_t major, isc_uint32_t minor,
d56ed2
 #endif
d56ed2
 
d56ed2
 isc_result_t
d56ed2
-dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
d56ed2
-		   isc_buffer_t *outtoken, gss_ctx_id_t *gssctx,
d56ed2
-		   isc_mem_t *mctx, char **err_message)
d56ed2
+dst_gssapi_initctx(dns_name_t *name, isc_boolean_t explicit_realm,
d56ed2
+		   isc_buffer_t *intoken, isc_buffer_t *outtoken,
d56ed2
+		   gss_ctx_id_t *gssctx, isc_mem_t *mctx, char **err_message)
d56ed2
 {
d56ed2
 #ifdef GSSAPI
d56ed2
 	isc_region_t r;
d56ed2
 	isc_buffer_t namebuf;
d56ed2
 	gss_name_t gname;
d56ed2
+	gss_OID gname_type;
d56ed2
 	OM_uint32 gret, minor, ret_flags, flags;
d56ed2
 	gss_buffer_desc gintoken, *gintokenp, gouttoken = GSS_C_EMPTY_BUFFER;
d56ed2
 	isc_result_t result;
d56ed2
@@ -580,7 +581,13 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
d56ed2
 	name_to_gbuffer(name, &namebuf, &gnamebuf);
d56ed2
 
d56ed2
 	/* Get the name as a GSS name */
d56ed2
-	gret = gss_import_name(&minor, &gnamebuf, GSS_C_NO_OID, &gname);
d56ed2
+	if (explicit_realm == ISC_TRUE) {
d56ed2
+		gname_type = GSS_C_NO_OID;
d56ed2
+	} else {
d56ed2
+		gname_type = GSS_C_NT_HOSTBASED_SERVICE;
d56ed2
+	}
d56ed2
+
d56ed2
+	gret = gss_import_name(&minor, &gnamebuf, gname_type, &gname);
d56ed2
 	if (gret != GSS_S_COMPLETE) {
d56ed2
 		gss_err_message(mctx, gret, minor, err_message);
d56ed2
 		result = ISC_R_FAILURE;
d56ed2
@@ -642,6 +649,7 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
d56ed2
 	return (result);
d56ed2
 #else
d56ed2
 	UNUSED(name);
d56ed2
+	UNUSED(explicit_realm);
d56ed2
 	UNUSED(intoken);
d56ed2
 	UNUSED(outtoken);
d56ed2
 	UNUSED(gssctx);
d56ed2
diff --git a/lib/dns/include/dns/tkey.h b/lib/dns/include/dns/tkey.h
d56ed2
index 0dcec1e..a0e6c2a 100644
d56ed2
--- a/lib/dns/include/dns/tkey.h
d56ed2
+++ b/lib/dns/include/dns/tkey.h
d56ed2
@@ -123,9 +123,9 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
d56ed2
 
d56ed2
 isc_result_t
d56ed2
 dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
d56ed2
-		       isc_buffer_t *intoken, isc_uint32_t lifetime,
d56ed2
-		       gss_ctx_id_t *context, isc_boolean_t win2k,
d56ed2
-		       isc_mem_t *mctx, char **err_message);
d56ed2
+		       isc_boolean_t explicit_realm, isc_buffer_t *intoken,
d56ed2
+		       isc_uint32_t lifetime, gss_ctx_id_t *context,
d56ed2
+		       isc_boolean_t win2k, isc_mem_t *mctx, char **err_message);
d56ed2
 /*%<
d56ed2
  *	Builds a query containing a TKEY that will generate a GSSAPI context.
d56ed2
  *	The key is requested to have the specified lifetime (in seconds).
d56ed2
@@ -134,6 +134,8 @@ dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
d56ed2
  *\li		'msg'	  is a valid message
d56ed2
  *\li		'name'	  is a valid name
d56ed2
  *\li		'gname'	  is a valid name
d56ed2
+ *\li		'explicit_realm' ISC_TRUE if an explicit realm is used,
d56ed2
+ *			  ISC_FALSE if the realm detection is left up to GSSAPI.
d56ed2
  *\li		'context' is a pointer to a valid gss_ctx_id_t
d56ed2
  *			  (which may have the value GSS_C_NO_CONTEXT)
d56ed2
  *\li		'win2k'   when true says to turn on some hacks to work
d56ed2
@@ -188,9 +190,10 @@ dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
 
d56ed2
 isc_result_t
d56ed2
 dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
-			    dns_name_t *gname, gss_ctx_id_t *context,
d56ed2
-			    isc_buffer_t *outtoken, dns_tsigkey_t **outkey,
d56ed2
-			    dns_tsig_keyring_t *ring, char **err_message);
d56ed2
+			    dns_name_t *gname, isc_boolean_t explicit_realm,
d56ed2
+			    gss_ctx_id_t *context, isc_buffer_t *outtoken,
d56ed2
+			    dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
d56ed2
+			    char **err_message);
d56ed2
 /*%<
d56ed2
  * XXX
d56ed2
  */
d56ed2
@@ -216,9 +219,10 @@ dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
 
d56ed2
 isc_result_t
d56ed2
 dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
-		      dns_name_t *server, gss_ctx_id_t *context,
d56ed2
-		      dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
d56ed2
-		      isc_boolean_t win2k, char **err_message);
d56ed2
+		      dns_name_t *server, isc_boolean_t explicit_realm,
d56ed2
+		      gss_ctx_id_t *context, dns_tsigkey_t **outkey,
d56ed2
+		      dns_tsig_keyring_t *ring, isc_boolean_t win2k,
d56ed2
+		      char **err_message);
d56ed2
 
d56ed2
 /*
d56ed2
  *	Client side negotiation of GSS-TSIG.  Process the response
d56ed2
@@ -231,6 +235,8 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
  *			     it will be filled with the new message to send
d56ed2
  *		'rmsg'    is a valid message, the incoming TKEY message
d56ed2
  *		'server'  is the server name
d56ed2
+ *		'explicit_realm' ISC_TRUE if an explicit realm is used,
d56ed2
+ *			      ISC_FALSE if the realm detection is left up to GSSAPI.
d56ed2
  *		'context' is the input context handle
d56ed2
  *		'outkey'  receives the established key, if non-NULL;
d56ed2
  *			      if non-NULL must point to NULL
d56ed2
diff --git a/lib/dns/include/dst/gssapi.h b/lib/dns/include/dst/gssapi.h
d56ed2
index 1e81a55..d093fa3 100644
d56ed2
--- a/lib/dns/include/dst/gssapi.h
d56ed2
+++ b/lib/dns/include/dst/gssapi.h
d56ed2
@@ -93,15 +93,17 @@ dst_gssapi_releasecred(gss_cred_id_t *cred);
d56ed2
  */
d56ed2
 
d56ed2
 isc_result_t
d56ed2
-dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
d56ed2
-		   isc_buffer_t *outtoken, gss_ctx_id_t *gssctx,
d56ed2
-		   isc_mem_t *mctx, char **err_message);
d56ed2
+dst_gssapi_initctx(dns_name_t *name, isc_boolean_t explicit_realm,
d56ed2
+		   isc_buffer_t *intoken, isc_buffer_t *outtoken,
d56ed2
+		   gss_ctx_id_t *gssctx, isc_mem_t *mctx, char **err_message);
d56ed2
 /*
d56ed2
  *	Initiates a GSS context.
d56ed2
  *
d56ed2
  *	Requires:
d56ed2
  * 	'name'     is a valid name, preferably one known by the GSS
d56ed2
  * 	provider
d56ed2
+ * 	'explicit_realm' True if the REALM is explicitly included in the 'name',
d56ed2
+ *  	   otherwise leave the REALM detection up to GSSAPI
d56ed2
  * 	'intoken'  is a token received from the acceptor, or NULL if
d56ed2
  *		   there isn't one
d56ed2
  * 	'outtoken' is a buffer to receive the token generated by
d56ed2
diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c
d56ed2
index 20c98e5..3463d3a 100644
d56ed2
--- a/lib/dns/tkey.c
d56ed2
+++ b/lib/dns/tkey.c
d56ed2
@@ -1016,9 +1016,9 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
d56ed2
 
d56ed2
 isc_result_t
d56ed2
 dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
d56ed2
-		       isc_buffer_t *intoken, isc_uint32_t lifetime,
d56ed2
-		       gss_ctx_id_t *context, isc_boolean_t win2k,
d56ed2
-		       isc_mem_t *mctx, char **err_message)
d56ed2
+		       isc_boolean_t explicit_realm, isc_buffer_t *intoken,
d56ed2
+		       isc_uint32_t lifetime, gss_ctx_id_t *context,
d56ed2
+		       isc_boolean_t win2k, isc_mem_t *mctx, char **err_message)
d56ed2
 {
d56ed2
 	dns_rdata_tkey_t tkey;
d56ed2
 	isc_result_t result;
d56ed2
@@ -1035,7 +1035,7 @@ dns_tkey_buildgssquery(dns_message_t *msg, dns_name_t *name, dns_name_t *gname,
d56ed2
 	REQUIRE(mctx != NULL);
d56ed2
 
d56ed2
 	isc_buffer_init(&token, array, sizeof(array));
d56ed2
-	result = dst_gssapi_initctx(gname, NULL, &token, context,
d56ed2
+	result = dst_gssapi_initctx(gname, explicit_realm, NULL, &token, context,
d56ed2
 				    mctx, err_message);
d56ed2
 	if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
d56ed2
 		return (result);
d56ed2
@@ -1251,9 +1251,10 @@ dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
 
d56ed2
 isc_result_t
d56ed2
 dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
-			    dns_name_t *gname, gss_ctx_id_t *context,
d56ed2
-			    isc_buffer_t *outtoken, dns_tsigkey_t **outkey,
d56ed2
-			    dns_tsig_keyring_t *ring, char **err_message)
d56ed2
+			    dns_name_t *gname, isc_boolean_t explicit_realm,
d56ed2
+			    gss_ctx_id_t *context, isc_buffer_t *outtoken,
d56ed2
+			    dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
d56ed2
+			    char **err_message)
d56ed2
 {
d56ed2
 	dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
d56ed2
 	dns_name_t *tkeyname;
d56ed2
@@ -1304,7 +1305,7 @@ dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
 
d56ed2
 	isc_buffer_init(outtoken, array, sizeof(array));
d56ed2
 	isc_buffer_init(&intoken, rtkey.key, rtkey.keylen);
d56ed2
-	RETERR(dst_gssapi_initctx(gname, &intoken, outtoken, context,
d56ed2
+	RETERR(dst_gssapi_initctx(gname, explicit_realm, &intoken, outtoken, context,
d56ed2
 				  ring->mctx, err_message));
d56ed2
 
d56ed2
 	RETERR(dst_key_fromgssapi(dns_rootname, *context, rmsg->mctx,
d56ed2
@@ -1384,9 +1385,10 @@ dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
 
d56ed2
 isc_result_t
d56ed2
 dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
-		      dns_name_t *server, gss_ctx_id_t *context,
d56ed2
-		      dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
d56ed2
-		      isc_boolean_t win2k, char **err_message)
d56ed2
+		      dns_name_t *server, isc_boolean_t explicit_realm,
d56ed2
+		      gss_ctx_id_t *context, dns_tsigkey_t **outkey,
d56ed2
+		      dns_tsig_keyring_t *ring, isc_boolean_t win2k,
d56ed2
+		      char **err_message)
d56ed2
 {
d56ed2
 	dns_rdata_t rtkeyrdata = DNS_RDATA_INIT, qtkeyrdata = DNS_RDATA_INIT;
d56ed2
 	dns_name_t *tkeyname;
d56ed2
@@ -1430,8 +1432,8 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
d56ed2
 	isc_buffer_init(&intoken, rtkey.key, rtkey.keylen);
d56ed2
 	isc_buffer_init(&outtoken, array, sizeof(array));
d56ed2
 
d56ed2
-	result = dst_gssapi_initctx(server, &intoken, &outtoken, context,
d56ed2
-				    ring->mctx, err_message);
d56ed2
+	result = dst_gssapi_initctx(server, explicit_realm, &intoken, &outtoken,
d56ed2
+					context, ring->mctx, err_message);
d56ed2
 	if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
d56ed2
 		return (result);
d56ed2
 
d56ed2
-- 
d56ed2
2.4.3
d56ed2