Patch to ignore service principals when accepting connexions.

Roland C. Dowdeswell elric at imrryr.org
Wed Aug 25 15:00:38 EDT 2010


In my environment, I generally recommend to application developers
that they pass arg 3 of gss_accept_sec_context as GSS_C_NO_CREDENTIAL
so that their servers will accept service tickets for any principal
defined in their keytab.  We find this to be quite important because
we have clients that will select different names to talk to the
same servers, including but not limited to: virtual IP addresses,
load balancers, different Kerberos library implementations,
differences in name service on different platforms.  The list goes
on and on.

The problem is, however, that we have vendor-provided software to
which we do not have src code which does not pass GSS_C_NO_CREDENTIAL
to gss_accept_sec_context().  And so, we'd like a mechanism to get
the behaviour that we'd like without regard to how the vendors
write their code.

Here's the proposal:

The Kerberos libs will stop enforcing that the service principal
name matches what the server requests in its call to krb5_rd_req()
if either:

	1.  ``check-service-principal'' in [libdefaults] is set to
	    false, or

	2.  the env var KRB5_CHECK_SERVICE_PRINCIPAL is set to either
	    0 or false.

The env var takes precendence over the krb5.conf setting.

And here's a quick patch that implements the proposal:

Index: include/k5-int.h
===================================================================
RCS file: /ms/.dev/kerberos/mitkrb5/CVS/mitkrb5-1.4/mitkrb5/src/include/k5-int.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 k5-int.h
--- include/k5-int.h	26 Sep 2006 20:29:10 -0000	1.1.1.2
+++ include/k5-int.h	25 Aug 2010 17:41:41 -0000
@@ -508,6 +508,8 @@
 
 void krb5_os_free_context (krb5_context);
 
+int krb5_os_check_service_principal (krb5_context);
+
 /* This function is needed by KfM's KerberosPreferences API 
  * because it needs to be able to specify "secure" */
 krb5_error_code os_get_default_config_files 
@@ -1057,6 +1059,7 @@
 
 
 #define KRB5_LIBOPT_SYNC_KDCTIME	0x0001
+#define KRB5_LIBOPT_IGNORE_SERVER_PRINC	0x0002
 
 /* internal message representations */
 
Index: lib/krb5/krb/init_ctx.c
===================================================================
RCS file: /ms/.dev/kerberos/mitkrb5/CVS/mitkrb5-1.4/mitkrb5/src/lib/krb5/krb/init_ctx.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 init_ctx.c
--- lib/krb5/krb/init_ctx.c	28 Mar 2005 21:43:36 -0000	1.1.1.1
+++ lib/krb5/krb/init_ctx.c	25 Aug 2010 17:48:07 -0000
@@ -209,7 +209,32 @@
 	profile_get_integer(ctx->profile, "libdefaults",
 			    "kdc_timesync", 0, DEFAULT_KDC_TIMESYNC,
 			    &tmp);
-	ctx->library_options = tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0;
+	ctx->library_options |= tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0;
+
+	/*
+	 * KRB5_LIBOPT_IGNORE_SERVER_PRINC may be reset by
+	 * krb5_os_init_context() and hence this must precede it.
+	 * We set the default value to -1 so that we can distinguish
+	 * between true, false and undefined.
+	 */
+	profile_get_boolean(ctx->profile, "libdefaults",
+			    "check-service-principal", 0,
+			    -1, &tmp);
+	if (tmp == 1)
+		ctx->library_options &= ~KRB5_LIBOPT_IGNORE_SERVER_PRINC;
+	if (tmp == 0)
+		ctx->library_options |= KRB5_LIBOPT_IGNORE_SERVER_PRINC;
+
+	switch (krb5_os_check_service_principal(ctx)) {
+	case 1:
+		ctx->library_options &= ~KRB5_LIBOPT_IGNORE_SERVER_PRINC;
+		break;
+	case 0:
+		ctx->library_options |= KRB5_LIBOPT_IGNORE_SERVER_PRINC;
+		break;
+	default:
+		break;
+	}
 
 	/*
 	 * We use a default file credentials cache of 3.  See
Index: lib/krb5/krb/rd_req.c
===================================================================
RCS file: /ms/.dev/kerberos/mitkrb5/CVS/mitkrb5-1.4/mitkrb5/src/lib/krb5/krb/rd_req.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 rd_req.c
--- lib/krb5/krb/rd_req.c	28 Mar 2005 21:43:36 -0000	1.1.1.1
+++ lib/krb5/krb/rd_req.c	25 Aug 2010 18:25:12 -0000
@@ -79,7 +79,7 @@
         *auth_context = new_auth_context;
     }
 
-    if (!server) {
+    if (context->library_options & KRB5_LIBOPT_IGNORE_SERVER_PRINC || !server) {
 	server = request->ticket->server;
     }
     /* Get an rcache if necessary. */
Index: lib/krb5/os/init_os_ctx.c
===================================================================
RCS file: /ms/.dev/kerberos/mitkrb5/CVS/mitkrb5-1.4/mitkrb5/src/lib/krb5/os/init_os_ctx.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 init_os_ctx.c
--- lib/krb5/os/init_os_ctx.c	16 Aug 2005 19:51:59 -0000	1.1.1.2
+++ lib/krb5/os/init_os_ctx.c	25 Aug 2010 17:40:34 -0000
@@ -375,6 +375,26 @@
 	return retval;
 }
 
+int KRB5_CALLCONV
+krb5_os_check_service_principal (krb5_context ctx)
+{
+#ifndef _WIN32
+	char *check_server;
+
+	check_server = getenv("KRB5_CHECK_SERVICE_PRINCIPAL");
+	if (check_server) {
+		if (!strcmp(check_server, "0") ||
+		    !strcasecmp(check_server, "false"))
+			return 0;
+		if (!strcmp(check_server, "1") ||
+		    !strcasecmp(check_server, "true"))
+			return 1;
+	}
+#endif /* _WIN32 */
+
+	return -1;
+}
+
 krb5_error_code KRB5_CALLCONV
 krb5_get_profile (krb5_context ctx, profile_t *profile)
 {



--
    Roland Dowdeswell                      http://Imrryr.ORG/~elric/



More information about the krbdev mailing list