Skip to Content.
Sympa Menu

freetds - [freetds] How to specify SPN when server is in a different realm (was Re: tds9 and gssapi)

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: Mike Slifcak <slif AT bellsouth.net>
  • To: freetds AT lists.ibiblio.org
  • Subject: [freetds] How to specify SPN when server is in a different realm (was Re: tds9 and gssapi)
  • Date: Thu, 11 Aug 2011 23:47:51 -0400

Hello.

If client is in one realm, and server is in another realm,
the server's realm name must follow the SPN before presenting it to
gss_import_name:

MSSQLSvc / hostnamefqdn : port @ server_realm_name [spaces for
illustration only!]


tds->connection has no string to hold server realm name ...
How hard would it be to add "ServerRealmName" and "server realm name" tokens
to
the ODBC and baseline configuration parsers?


I've attached an exploratory (compiles, not tested) patch that adds server
realm
before gss_import_name is called.
The patch also adds configuration parsing for the server realm name.

I wasn't sure where to add config for ODBC, so I didn't add that.

Let me know where the patch needs work.

Thanks in advance,
-Mike Slifcak

Offered by:  Mike Slifcak
Apply to: freetds-0.91.dev.20110804RC2
Impact:   add "server realm name" token to config
	add external realm to SPN during GSSAPI token creation

Compiled:  Yes
Tested:	NOT TESTED


diff -urp a/include/tds.h b/include/tds.h
--- a/include/tds.h	2011-08-11 22:26:20.000000000 -0400
+++ b/include/tds.h	2011-08-11 22:26:33.000000000 -0400
@@ -815,6 +815,7 @@ typedef enum tds_encryption_level {
 #define TDS_STR_ENCRYPTION_REQUIRE "require"
 /* Defines to enable optional GSSAPI delegation */
 #define TDS_GSSAPI_DELEGATION "enable gssapi delegation"
+#define TDS_STR_REALM  "server realm name"
 
 
 /* TODO do a better check for alignment than this */
@@ -887,6 +888,7 @@ typedef struct tds_connection
 	unsigned int suppress_language:1;
 	unsigned int gssapi_use_delegation:1;
 	unsigned int use_ntlmv2:1;
+	DSTR server_realm_name; /**< server realm name (in freetds.conf) */
 } TDSCONNECTION;
 
 typedef struct tds_locale
diff -urp a/src/tds/config.c b/src/tds/config.c
--- a/src/tds/config.c	2011-04-15 02:59:16.000000000 -0400
+++ b/src/tds/config.c	2011-08-11 22:33:37.000000000 -0400
@@ -252,6 +252,7 @@ tds_read_config_info(TDSSOCKET * tds, TD
 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "text_size", connection->text_size);
 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "broken_dates", connection->broken_dates);
 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "emul_little_endian", connection->emul_little_endian);
+		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_realm_name", tds_dstr_cstr(&connection->server_realm_name));
 
 		tdsdump_close();
 	}
@@ -622,6 +623,8 @@ tds_parse_conf_section(const char *optio
 		tds_dstr_copy(&connection->server_name, value);
 	} else if (!strcmp(option, TDS_STR_USENTLMV2)) {
 		connection->use_ntlmv2 = tds_config_boolean(value);
+	} else if (!strcmp(option, TDS_STR_REALM)) {
+		tds_dstr_copy(&connection->server_realm_name, value);
 	} else {
 		tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED option '%s' ... ignoring.\n", option);
 	}
diff -urp a/src/tds/gssapi.c b/src/tds/gssapi.c
--- a/src/tds/gssapi.c	2011-05-10 09:21:30.000000000 -0400
+++ b/src/tds/gssapi.c	2011-08-11 22:22:55.000000000 -0400
@@ -177,6 +177,7 @@ tds_gss_get_auth(TDSSOCKET * tds)
 	/* same as GSS_KRB5_NT_PRINCIPAL_NAME but do not require .so library */
 	static gss_OID_desc nt_principal = { 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01" };
 	const char *server_name;
+	const char *server_realm_name;
 	/* Storage for reentrant getaddrby* calls */
 	char buffer[4096];
 
@@ -199,11 +200,19 @@ tds_gss_get_auth(TDSSOCKET * tds)
 		if (host && strchr(host->h_name, '.') != NULL)
 			server_name = host->h_name;
 	}
-
+	server_realm_name = tds_dstr_cstr(&tds->connection->server_realm_name);
+	if (server_realm_name == NULL) {
 	if (asprintf(&auth->sname, "MSSQLSvc/%s:%d", server_name, tds->connection->port) < 0) {
 		tds_gss_free(tds, (TDSAUTHENTICATION *) auth);
 		return NULL;
 	}
+	}
+	else {
+	if (asprintf(&auth->sname, "MSSQLSvc/%s:%d@%s", server_name, tds->connection->port, server_realm_name) < 0) {
+		tds_gss_free(tds, (TDSAUTHENTICATION *) auth);
+		return NULL;
+	}
+	}
 	tdsdump_log(TDS_DBG_NETWORK, "kerberos name %s\n", auth->sname);
 
 	/*
@@ -214,8 +223,13 @@ tds_gss_get_auth(TDSSOCKET * tds)
 	send_tok.length = strlen(auth->sname);
 	maj_stat = gss_import_name(&min_stat, &send_tok, &nt_principal, &auth->target_name);
 
-	if (maj_stat != GSS_S_COMPLETE
-	    || tds_gss_continue(tds, auth, GSS_C_NO_BUFFER) == TDS_FAIL) {
+	if (maj_stat != GSS_S_COMPLETE) {
+	    tdsdump_log(TDS_DBG_NETWORK, "gss_import_name failed %d\n", maj_stat);
+		tds_gss_free(tds, (TDSAUTHENTICATION *) auth);
+		return NULL;
+	}
+
+	if (tds_gss_continue(tds, auth, GSS_C_NO_BUFFER) == TDS_FAIL) {
 		tds_gss_free(tds, (TDSAUTHENTICATION *) auth);
 		return NULL;
 	}
@@ -268,6 +282,8 @@ tds_gss_continue(TDSSOCKET * tds, struct
 
 	auth->last_stat = maj_stat;
 	if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {
+		tdsdump_log(TDS_DBG_NETWORK, "gss_init_sec_context flags %x, returns %x\n", gssapi_flags, maj_stat);
+/*XX dump send_tok return contents if debug_flags allows,etc. */
 		gss_release_buffer(&min_stat, &send_tok);
 		return TDS_FAIL;
 	}
diff -urp a/src/tds/mem.c b/src/tds/mem.c
--- a/src/tds/mem.c	2010-09-28 04:20:11.000000000 -0400
+++ b/src/tds/mem.c	2011-08-11 22:36:35.000000000 -0400
@@ -827,6 +827,7 @@ tds_alloc_connection(TDSLOCALE * locale)
 	tds_dstr_init(&connection->dump_file);
 	tds_dstr_init(&connection->client_charset);
 	tds_dstr_init(&connection->instance_name);
+	tds_dstr_init(&connection->server_realm_name);
 
 	/* fill in all hardcoded defaults */
 	if (!tds_dstr_copy(&connection->server_name, TDS_DEF_SERVER))
@@ -1188,6 +1189,7 @@ tds_free_connection(TDSCONNECTION * conn
 	tds_dstr_free(&connection->password);
 	tds_dstr_free(&connection->library);
 	tds_dstr_free(&connection->instance_name);
+	tds_dstr_free(&connection->server_realm_name);
 	free(connection);
 }
 



  • [freetds] How to specify SPN when server is in a different realm (was Re: tds9 and gssapi), Mike Slifcak, 08/11/2011

Archive powered by MHonArc 2.6.24.

Top of Page